1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-09 01:05:38 +02:00

C++: enumerations, enumerators and pointers to functions

This commit is contained in:
Andrew Niefer 2004-12-15 17:09:04 +00:00
parent 8e1dc14197
commit 7c6a5a0094
6 changed files with 381 additions and 75 deletions

View file

@ -25,10 +25,16 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBasicType;
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.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.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; 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.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
@ -594,5 +600,142 @@ public class AST2CPPTests extends AST2BaseTest {
assertInstances( collector, A, 2 ); assertInstances( collector, A, 2 );
assertInstances( collector, x, 2 ); assertInstances( collector, x, 2 );
} }
public void testEnumerations() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "enum hue { red, blue, green }; \n" ); //$NON-NLS-1$
buffer.append( "enum hue col, *cp; \n" ); //$NON-NLS-1$
buffer.append( "void f() { \n" ); //$NON-NLS-1$
buffer.append( " col = blue; \n" ); //$NON-NLS-1$
buffer.append( " cp = &col; \n" ); //$NON-NLS-1$
buffer.append( " if( *cp != red ) \n" ); //$NON-NLS-1$
buffer.append( " return; \n" ); //$NON-NLS-1$
buffer.append( "} \n" ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector collector = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, collector );
IEnumeration hue = (IEnumeration) collector.getName(0).resolveBinding();
IEnumerator red = (IEnumerator) collector.getName(1).resolveBinding();
IEnumerator blue = (IEnumerator) collector.getName(2).resolveBinding();
IEnumerator green = (IEnumerator) collector.getName(3).resolveBinding();
IVariable col = (IVariable) collector.getName(5).resolveBinding();
IVariable cp = (IVariable) collector.getName(6).resolveBinding();
assertInstances( collector, hue, 2 );
assertInstances( collector, red, 2 );
assertInstances( collector, blue, 2 );
assertInstances( collector, green, 1 );
assertInstances( collector, col, 3 );
assertInstances( collector, cp, 3 );
assertTrue( cp.getType() instanceof IPointerType );
IPointerType pt = (IPointerType) cp.getType();
assertSame( pt.getType(), hue );
}
public void testPointerToFunction() throws Exception{
IASTTranslationUnit tu = parse( "int (*pfi)();", ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector collector = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, collector );
IVariable pf = (IVariable) collector.getName(0).resolveBinding();
IPointerType pt = (IPointerType) pf.getType();
assertTrue( pt.getType() instanceof IFunctionType );
tu = parse( "struct A; int (*pfi)( int, struct A * );", ParserLanguage.CPP ); //$NON-NLS-1$
collector = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, collector );
ICPPClassType A = (ICPPClassType) collector.getName(0).resolveBinding();
pf = (IVariable) collector.getName(1).resolveBinding();
pt = (IPointerType) pf.getType();
assertTrue( pt.getType() instanceof IFunctionType );
IFunctionType ft = (IFunctionType) pt.getType();
IType [] params = ft.getParameterTypes();
assertTrue( params[0] instanceof IBasicType );
assertTrue( params[1] instanceof IPointerType );
pt = (IPointerType) params[1];
assertSame( pt.getType(), A );
}
public void testFunctionTypes() throws Exception{
StringBuffer buffer = new StringBuffer();
buffer.append( "struct A; \n"); //$NON-NLS-1$
buffer.append( "int * f( int i, char c ); \n"); //$NON-NLS-1$
buffer.append( "void ( *g ) ( A * ); \n"); //$NON-NLS-1$
buffer.append( "void (* (*h)(A**) ) ( int ); \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTElaboratedTypeSpecifier elabSpec = (IASTElaboratedTypeSpecifier) decl.getDeclSpecifier();
ICompositeType A = (ICompositeType) elabSpec.getName().resolveBinding();
decl = (IASTSimpleDeclaration) tu.getDeclarations()[1];
IFunction f = (IFunction) decl.getDeclarators()[0].getName().resolveBinding();
decl = (IASTSimpleDeclaration) tu.getDeclarations()[2];
IVariable g = (IVariable) decl.getDeclarators()[0].getNestedDeclarator().getName().resolveBinding();
decl = (IASTSimpleDeclaration) tu.getDeclarations()[3];
IVariable h = (IVariable) decl.getDeclarators()[0].getNestedDeclarator().getNestedDeclarator().getName().resolveBinding();
IFunctionType t_f = f.getType();
IType t_f_return = t_f.getReturnType();
assertTrue( t_f_return instanceof IPointerType );
assertTrue( ((IPointerType) t_f_return).getType() instanceof IBasicType );
IType [] t_f_params = t_f.getParameterTypes();
assertEquals( t_f_params.length, 2 );
assertTrue( t_f_params[0] instanceof IBasicType );
assertTrue( t_f_params[1] instanceof IBasicType );
//g is a pointer to a function that returns void and has 1 parameter struct A *
IType t_g = g.getType();
assertTrue( t_g instanceof IPointerType );
assertTrue( ((IPointerType) t_g).getType() instanceof IFunctionType );
IFunctionType t_g_func = (IFunctionType) ((IPointerType) t_g).getType();
IType t_g_func_return = t_g_func.getReturnType();
assertTrue( t_g_func_return instanceof IBasicType );
IType [] t_g_func_params = t_g_func.getParameterTypes();
assertEquals( t_g_func_params.length, 1 );
IType t_g_func_p1 = t_g_func_params[0];
assertTrue( t_g_func_p1 instanceof IPointerType );
assertSame( ((IPointerType)t_g_func_p1).getType(), A );
//h is a pointer to a function that returns a pointer to a function
//the returned pointer to function returns void and takes 1 parameter int
// the *h function takes 1 parameter struct A**
IType t_h = h.getType();
assertTrue( t_h instanceof IPointerType );
assertTrue( ((IPointerType) t_h).getType() instanceof IFunctionType );
IFunctionType t_h_func = (IFunctionType) ((IPointerType) t_h).getType();
IType t_h_func_return = t_h_func.getReturnType();
IType [] t_h_func_params = t_h_func.getParameterTypes();
assertEquals( t_h_func_params.length, 1 );
IType t_h_func_p1 = t_h_func_params[0];
assertTrue( t_h_func_p1 instanceof IPointerType );
assertTrue( ((IPointerType)t_h_func_p1).getType() instanceof IPointerType );
assertSame( ((IPointerType) ((IPointerType)t_h_func_p1).getType() ).getType(), A );
assertTrue( t_h_func_return instanceof IPointerType );
IFunctionType h_return = (IFunctionType) ((IPointerType) t_h_func_return).getType();
IType h_r = h_return.getReturnType();
IType [] h_ps = h_return.getParameterTypes();
assertTrue( h_r instanceof IBasicType );
assertEquals( h_ps.length, 1 );
assertTrue( h_ps[0] instanceof IBasicType );
}
public void testFnReturningPtrToFn() throws Exception {
IASTTranslationUnit tu = parse( "void ( * f( int ) )(){}", ParserLanguage.CPP ); //$NON-NLS-1$
IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[0];
IFunction f = (IFunction) def.getDeclarator().getNestedDeclarator().getName().resolveBinding();
IFunctionType ft = f.getType();
assertTrue( ft.getReturnType() instanceof IPointerType );
assertTrue( ((IPointerType) ft.getReturnType()).getType() instanceof IFunctionType );
assertEquals( ft.getParameterTypes().length, 1 );
}
} }

View file

@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/*
* Created on Dec 14, 2004
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IScope;
/**
* @author aniefer
*/
public class CPPEnumeration implements IEnumeration {
private IASTEnumerationSpecifier enumSpecifier;
/**
* @param specifier
*/
public CPPEnumeration( IASTEnumerationSpecifier specifier ) {
this.enumSpecifier = specifier;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return enumSpecifier.getName().toString();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return enumSpecifier.getName().toCharArray();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
public IScope getScope() {
return CPPVisitor.getContainingScope( enumSpecifier );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return enumSpecifier;
}
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/*
* Created on Dec 14, 2004
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
/**
* @author aniefer
*/
public class CPPEnumerator implements IEnumerator {
private IASTEnumerator enumerator;
/**
* @param enumerator
*/
public CPPEnumerator( IASTEnumerator enumerator ) {
this.enumerator = enumerator;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return enumerator.getName().toString();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return enumerator.getName().toCharArray();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
public IScope getScope() {
return CPPVisitor.getContainingScope( enumerator );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return enumerator;
}
}

View file

@ -125,7 +125,7 @@ public class CPPFunction implements IFunction {
*/ */
public IFunctionType getType() { public IFunctionType getType() {
if( type == null ) if( type == null )
type = CPPVisitor.createType( ( definition != null ) ? definition : declarations[0] ); type = (IFunctionType) CPPVisitor.createType( ( definition != null ) ? definition : declarations[0] );
return type; return type;
} }

View file

@ -13,13 +13,8 @@
*/ */
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
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.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
@ -29,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
*/ */
public class CPPVariable implements IVariable { public class CPPVariable implements IVariable {
private IASTDeclarator declarator = null; private IASTDeclarator declarator = null;
private IType type = null;
public CPPVariable( IASTDeclarator dtor ){ public CPPVariable( IASTDeclarator dtor ){
declarator = dtor; declarator = dtor;
@ -38,17 +34,9 @@ public class CPPVariable implements IVariable {
* @see org.eclipse.cdt.core.dom.ast.IVariable#getType() * @see org.eclipse.cdt.core.dom.ast.IVariable#getType()
*/ */
public IType getType() { public IType getType() {
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) declarator.getParent(); if( type == null )
IASTDeclSpecifier declSpec = decl.getDeclSpecifier(); type = CPPVisitor.createType( declarator );
return type;
if( declSpec instanceof IASTNamedTypeSpecifier )
return (IType) ((IASTNamedTypeSpecifier)declSpec).getName().resolveBinding();
else if( declSpec instanceof IASTCompositeTypeSpecifier )
return (IType) ((IASTCompositeTypeSpecifier)declSpec).getName().resolveBinding();
else if( declSpec instanceof IASTElaboratedTypeSpecifier )
return (IType) ((IASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
return null;
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -133,20 +133,46 @@ public class CPPVisitor {
return createBinding( (IASTDeclarator) parent ); return createBinding( (IASTDeclarator) parent );
} else if( parent instanceof ICPPASTElaboratedTypeSpecifier ){ } else if( parent instanceof ICPPASTElaboratedTypeSpecifier ){
return createBinding( (ICPPASTElaboratedTypeSpecifier) parent ); return createBinding( (ICPPASTElaboratedTypeSpecifier) parent );
} else if( parent instanceof IASTDeclaration ) } else if( parent instanceof IASTDeclaration ){
return createBinding( (IASTDeclaration) parent ); return createBinding( (IASTDeclaration) parent );
} else if( parent instanceof IASTEnumerationSpecifier ){
return createBinding( (IASTEnumerationSpecifier) parent );
} else if( parent instanceof IASTEnumerator ){
return createBinding( (IASTEnumerator) parent );
}
return null; return null;
} }
private static IBinding createBinding( IASTEnumerator enumerator ) {
ICPPScope scope = (ICPPScope) getContainingScope( enumerator );
IBinding enum = scope.getBinding( enumerator.getName() );
if( enum == null ){
enum = new CPPEnumerator( enumerator );
scope.addBinding( enum );
}
return enum;
}
private static IBinding createBinding( IASTEnumerationSpecifier specifier ) {
ICPPScope scope = (ICPPScope) getContainingScope( specifier );
IBinding enum = scope.getBinding( specifier.getName() );
if( enum == null ){
enum = new CPPEnumeration( specifier );
scope.addBinding( enum );
}
return enum;
}
private static IBinding createBinding( ICPPASTElaboratedTypeSpecifier elabType ){ private static IBinding createBinding( ICPPASTElaboratedTypeSpecifier elabType ){
IASTNode parent = elabType.getParent(); IASTNode parent = elabType.getParent();
if( parent instanceof IASTSimpleDeclaration ){ if( parent instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)parent).getDeclarators(); IASTDeclarator [] dtors = ((IASTSimpleDeclaration)parent).getDeclarators();
if( dtors.length > 0 ){ if( dtors.length > 0 ){
IBinding binding = CPPSemantics.resolveBinding( elabType.getName() ); return CPPSemantics.resolveBinding( elabType.getName() );
if( binding != null )
return binding;
} }
} else if( parent instanceof IASTParameterDeclaration ){
return CPPSemantics.resolveBinding( elabType.getName() );
} else if( parent instanceof IASTTypeId ){ } else if( parent instanceof IASTTypeId ){
return CPPSemantics.resolveBinding( elabType.getName() ); return CPPSemantics.resolveBinding( elabType.getName() );
} }
@ -191,12 +217,19 @@ public class CPPVisitor {
return null; return null;
} }
private static IBinding createBinding( IASTDeclarator declarator ){ private static IBinding createBinding( IASTDeclarator declarator ){
IASTNode parent = declarator.getParent(); IASTNode parent = declarator.getParent();
if( parent instanceof IASTTypeId ) if( parent instanceof IASTTypeId )
return CPPSemantics.resolveBinding( declarator.getName() ); return CPPSemantics.resolveBinding( declarator.getName() );
if( declarator.getNestedDeclarator() != null )
return createBinding( declarator.getNestedDeclarator() );
while( parent instanceof IASTDeclarator ){
parent = parent.getParent();
}
ICPPScope scope = (ICPPScope) getContainingScope( parent ); ICPPScope scope = (ICPPScope) getContainingScope( parent );
IBinding binding = ( scope != null ) ? scope.getBinding( declarator.getName() ) : null; IBinding binding = ( scope != null ) ? scope.getBinding( declarator.getName() ) : null;
@ -204,7 +237,7 @@ public class CPPVisitor {
if( binding != null && binding instanceof IFunction ){ if( binding != null && binding instanceof IFunction ){
IFunction function = (IFunction) binding; IFunction function = (IFunction) binding;
IFunctionType ftype = function.getType(); IFunctionType ftype = function.getType();
IType type = createType( (ICPPASTFunctionDeclarator) declarator ); IType type = createType( declarator );
if( ftype.equals( type ) ){ if( ftype.equals( type ) ){
if( parent instanceof IASTSimpleDeclaration ) if( parent instanceof IASTSimpleDeclaration )
((CPPFunction)function).addDeclaration( (ICPPASTFunctionDeclarator) declarator ); ((CPPFunction)function).addDeclaration( (ICPPASTFunctionDeclarator) declarator );
@ -216,10 +249,15 @@ public class CPPVisitor {
} }
if( scope instanceof ICPPClassScope ) if( scope instanceof ICPPClassScope )
binding = new CPPMethod( (ICPPASTFunctionDeclarator) declarator ); binding = new CPPMethod( (ICPPASTFunctionDeclarator) declarator );
else else {
binding = new CPPFunction( (ICPPASTFunctionDeclarator) declarator ); binding = new CPPFunction( (ICPPASTFunctionDeclarator) declarator );
} else { }
if( parent instanceof IASTSimpleDeclaration ){ } else if( parent instanceof IASTParameterDeclaration ){
IASTParameterDeclaration param = (IASTParameterDeclaration) parent;
IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent();
IFunction function = (IFunction) fDtor.getName().resolveBinding();
binding = ((CPPFunction) function).resolveParameter( param );
} else if( parent instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent; IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent;
if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){ if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){
binding = new CPPTypedef( declarator ); binding = new CPPTypedef( declarator );
@ -228,16 +266,9 @@ public class CPPVisitor {
} else { } else {
binding = new CPPVariable( declarator ); binding = new CPPVariable( declarator );
} }
} else if( parent instanceof IASTParameterDeclaration ){ }
IASTParameterDeclaration param = (IASTParameterDeclaration) parent;
IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent();
IFunction function = (IFunction) fDtor.getName().resolveBinding();
binding = ((CPPFunction) function).resolveParameter( param );
} else if( parent instanceof IASTFunctionDefinition ){
} if( scope != null && binding != null )
}
if( scope != null )
scope.addBinding( binding ); scope.addBinding( binding );
return binding; return binding;
} }
@ -350,7 +381,7 @@ public class CPPVisitor {
return getContainingScope( (IASTSimpleDeclaration) parent ); return getContainingScope( (IASTSimpleDeclaration) parent );
else if( parent instanceof IASTTypeId ) else if( parent instanceof IASTTypeId )
return getContainingScope( parent.getParent() ); return getContainingScope( parent.getParent() );
return null; return getContainingScope( parent );
} }
/** /**
@ -361,9 +392,14 @@ public class CPPVisitor {
IASTNode parent = parameterDeclaration.getParent(); IASTNode parent = parameterDeclaration.getParent();
if( parent instanceof IASTFunctionDeclarator ){ if( parent instanceof IASTFunctionDeclarator ){
IASTFunctionDeclarator functionDeclarator = (IASTFunctionDeclarator) parent; IASTFunctionDeclarator functionDeclarator = (IASTFunctionDeclarator) parent;
if( functionDeclarator.getNestedDeclarator() != null ){
return getContainingScope( functionDeclarator );
}
IASTName fnName = functionDeclarator.getName(); IASTName fnName = functionDeclarator.getName();
IFunction function = (IFunction) fnName.resolveBinding(); IBinding binding = fnName.resolveBinding();
return function.getFunctionScope(); if( binding instanceof IFunction )
return ((IFunction)binding).getFunctionScope();
return binding.getScope();
} }
return null; return null;
@ -793,7 +829,7 @@ public class CPPVisitor {
return true; return true;
} }
public static IFunctionType createType( ICPPASTFunctionDeclarator fnDtor ){ private static IType createType( IType returnType, ICPPASTFunctionDeclarator fnDtor ){
List pTypes = Collections.EMPTY_LIST; List pTypes = Collections.EMPTY_LIST;
IASTParameterDeclaration [] params = fnDtor.getParameters(); IASTParameterDeclaration [] params = fnDtor.getParameters();
IType pt = null; IType pt = null;
@ -830,39 +866,26 @@ public class CPPVisitor {
pTypes.add( pt ); pTypes.add( pt );
} }
IASTNode node = fnDtor.getParent();
IASTDeclSpecifier declSpec = null;
if( node instanceof IASTSimpleDeclaration )
declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier();
else if ( node instanceof IASTFunctionDefinition )
declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier();
IType returnType = createType( declSpec );
returnType = getPointerTypes( returnType, fnDtor ); returnType = getPointerTypes( returnType, fnDtor );
IType [] array = new IType [ pTypes.size() ]; IType [] array = new IType [ pTypes.size() ];
return new CPPFunctionType( returnType, (IType[]) pTypes.toArray( array ) ); IType type = new CPPFunctionType( returnType, (IType[]) pTypes.toArray( array ) );
IASTDeclarator nested = fnDtor.getNestedDeclarator();
if( nested != null ) {
return createType( type, nested );
}
return type;
} }
/** /**
* @param declarator * @param declarator
* @return * @return
*/ */
public static IType createType(IASTDeclarator declarator) { private static IType createType(IType baseType, IASTDeclarator declarator) {
if( declarator instanceof ICPPASTFunctionDeclarator ) if( declarator instanceof ICPPASTFunctionDeclarator )
return createType( (ICPPASTFunctionDeclarator)declarator ); return createType( baseType, (ICPPASTFunctionDeclarator)declarator );
IASTNode parent = declarator.getParent();
IASTDeclSpecifier declSpec = null;
if( parent instanceof IASTParameterDeclaration )
declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
else if( parent instanceof IASTSimpleDeclaration )
declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier();
else if( parent instanceof IASTTypeId )
declSpec = ((IASTTypeId)parent).getDeclSpecifier();
IType type = createType( declSpec );
IType type = baseType;
type = getPointerTypes( type, declarator ); type = getPointerTypes( type, declarator );
if( declarator instanceof IASTArrayDeclarator ) if( declarator instanceof IASTArrayDeclarator )
type = getArrayTypes( type, (IASTArrayDeclarator) declarator ); type = getArrayTypes( type, (IASTArrayDeclarator) declarator );
@ -884,11 +907,35 @@ public class CPPVisitor {
return type; return type;
} }
/**
* @param declarator
* @return
*/
public static IType createType(IASTDeclarator declarator) {
IASTDeclSpecifier declSpec = null;
IASTNode node = declarator.getParent();
while( node instanceof IASTDeclarator ){
declarator = (IASTDeclarator) node;
node = node.getParent();
}
if( node instanceof IASTParameterDeclaration )
declSpec = ((IASTParameterDeclaration) node).getDeclSpecifier();
else if( node instanceof IASTSimpleDeclaration )
declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier();
else if( node instanceof IASTFunctionDefinition )
declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier();
IType type = createType( declSpec );
type = createType( type, declarator );
return type;
}
/** /**
* @param declSpec * @param declSpec
* @return * @return
*/ */
protected static IType createType(IASTDeclSpecifier declSpec ) { public static IType createType(IASTDeclSpecifier declSpec ) {
IType type = getBaseType( declSpec ); IType type = getBaseType( declSpec );
if( type != null && ( declSpec.isConst() || declSpec.isVolatile() ) ){ if( type != null && ( declSpec.isConst() || declSpec.isVolatile() ) ){
@ -903,6 +950,10 @@ public class CPPVisitor {
IBinding binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding(); IBinding binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding();
if( binding instanceof IType) if( binding instanceof IType)
type = (IType) binding; type = (IType) binding;
} else if( declSpec instanceof ICPPASTNamedTypeSpecifier ){
IBinding binding = ((ICPPASTNamedTypeSpecifier)declSpec).getName().resolveBinding();
if( binding instanceof IType )
type = (IType) binding;
} else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier ){ } else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier ){
IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
if( binding instanceof IType ) if( binding instanceof IType )
@ -937,7 +988,8 @@ public class CPPVisitor {
} }
} else if( expression instanceof IASTCastExpression ){ } else if( expression instanceof IASTCastExpression ){
IASTTypeId id = ((IASTCastExpression)expression).getTypeId(); IASTTypeId id = ((IASTCastExpression)expression).getTypeId();
return createType( id.getAbstractDeclarator() ); IType type = createType( id.getDeclSpecifier() );
return createType( type, id.getAbstractDeclarator() );
} else if( expression instanceof ICPPASTLiteralExpression ){ } else if( expression instanceof ICPPASTLiteralExpression ){
switch( ((ICPPASTLiteralExpression) expression).getKind() ){ switch( ((ICPPASTLiteralExpression) expression).getKind() ){
case ICPPASTLiteralExpression.lk_this : break; case ICPPASTLiteralExpression.lk_this : break;