1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-16 21:45:22 +02:00

Patch for Devin Steffler.

Fix for 108 Perrors in Dave's test associated with testTypedefExample4b (changes made to GNUCSourceParser)
	Better support for Function Types
This commit is contained in:
John Camelon 2004-12-21 16:27:04 +00:00
parent 4389ea8a9b
commit ee26471851
4 changed files with 302 additions and 31 deletions

View file

@ -1197,6 +1197,31 @@ public class AST2Tests extends AST2BaseTest {
assertTrue( ((IPointerType)ft.getParameterTypes()[0]).isConst() );
}
public void testFunctionDefTypes() throws Exception {
StringBuffer buffer = new StringBuffer( "int f() {}\n" ); //$NON-NLS-1$
buffer.append("int *f2() {}\n"); //$NON-NLS-1$
buffer.append("int (* f3())() {}\n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); //$NON-NLS-1$
IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[0];
IFunction f = (IFunction) def.getDeclarator().getName().resolveBinding();
def = (IASTFunctionDefinition) tu.getDeclarations()[1];
IFunction f2 = (IFunction) def.getDeclarator().getName().resolveBinding();
def = (IASTFunctionDefinition) tu.getDeclarations()[2];
IFunction f3 = (IFunction) def.getDeclarator().getName().resolveBinding();
IFunctionType ft = f.getType();
IFunctionType ft2 = f2.getType();
IFunctionType ft3 = f3.getType();
assertTrue( ft.getReturnType() instanceof IBasicType );
assertTrue( ft2.getReturnType() instanceof IPointerType );
assertTrue( ((IPointerType)ft2.getReturnType()).getType() instanceof IBasicType );
assertTrue( ft3.getReturnType() instanceof IPointerType );
assertTrue( ((IPointerType)ft3.getReturnType()).getType() instanceof IFunctionType );
assertTrue( ((IFunctionType)((IPointerType)ft3.getReturnType()).getType()).getReturnType() instanceof IBasicType );
}
// any parameter to type function returning T is adjusted to be pointer to function returning T
public void testParmToFunction() throws Exception {
IASTTranslationUnit tu = parse( "int f(int g(void)) { return g();}", ParserLanguage.C ); //$NON-NLS-1$
@ -1245,4 +1270,146 @@ public class AST2Tests extends AST2BaseTest {
assertTrue( vpt_2_2 instanceof IBasicType );
assertEquals( ((IBasicType)vpt_2_2).getType(), IBasicType.t_int );
}
public void testTypedefExample4a() throws Exception {
StringBuffer buffer = new StringBuffer( "typedef void DWORD;\n" ); //$NON-NLS-1$
buffer.append( "typedef DWORD v;\n" ); //$NON-NLS-1$
buffer.append( "v signal(int);\n" ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C );
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0];
ITypedef dword = (ITypedef)decl.getDeclarators()[0].getName().resolveBinding();
IType dword_t = dword.getType();
assertTrue( dword_t instanceof IBasicType );
assertEquals( ((IBasicType)dword_t).getType(), IBasicType.t_void );
decl = (IASTSimpleDeclaration) tu.getDeclarations()[1];
ITypedef v = (ITypedef)decl.getDeclarators()[0].getName().resolveBinding();
IType v_t_1 = v.getType();
assertTrue( v_t_1 instanceof ITypedef );
IType v_t_2 = ((ITypedef)v_t_1).getType();
assertTrue( v_t_2 instanceof IBasicType );
assertEquals( ((IBasicType)v_t_2).getType(), IBasicType.t_void );
decl = (IASTSimpleDeclaration) tu.getDeclarations()[2];
IFunction signal = (IFunction)decl.getDeclarators()[0].getName().resolveBinding();
IFunctionType signal_t = signal.getType();
IType signal_ret = signal_t.getReturnType();
assertTrue( signal_ret instanceof ITypedef );
IType signal_ret2 = ((ITypedef)signal_ret).getType();
assertTrue( signal_ret2 instanceof ITypedef );
IType signal_ret3 = ((ITypedef)signal_ret2).getType();
assertTrue( signal_ret3 instanceof IBasicType );
assertEquals( ((IBasicType)signal_ret3).getType(), IBasicType.t_void );
}
public void testTypedefExample4b() throws Exception {
StringBuffer buffer = new StringBuffer( "typedef void DWORD;\n" ); //$NON-NLS-1$
buffer.append( "typedef DWORD (*pfv)(int);\n" ); //$NON-NLS-1$
buffer.append( "pfv signal(int, pfv);\n" ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C );
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0];
ITypedef dword = (ITypedef)decl.getDeclarators()[0].getName().resolveBinding();
IType dword_t = dword.getType();
assertTrue( dword_t instanceof IBasicType );
assertEquals( ((IBasicType)dword_t).getType(), IBasicType.t_void );
decl = (IASTSimpleDeclaration) tu.getDeclarations()[1];
ITypedef pfv = (ITypedef)decl.getDeclarators()[0].getNestedDeclarator().getName().resolveBinding();
IType pfv_t_1 = pfv.getType();
assertTrue( pfv_t_1 instanceof IPointerType );
IType pfv_t_2 = ((IPointerType)pfv_t_1).getType();
assertTrue( pfv_t_2 instanceof IFunctionType );
IType pfv_t_2_ret_1 = ((IFunctionType)pfv_t_2).getReturnType();
assertTrue( pfv_t_2_ret_1 instanceof ITypedef );
IType pfv_t_2_ret_2 = ((ITypedef)pfv_t_2_ret_1).getType();
assertTrue( pfv_t_2_ret_2 instanceof IBasicType );
assertEquals( ((IBasicType)pfv_t_2_ret_2).getType(), IBasicType.t_void );
assertTrue( ((ITypedef)pfv_t_2_ret_1).getName().equals("DWORD") ); //$NON-NLS-1$
IType pfv_t_2_parm = ((IFunctionType)pfv_t_2).getParameterTypes()[0];
assertTrue( pfv_t_2_parm instanceof IBasicType );
assertEquals( ((IBasicType)pfv_t_2_parm).getType(), IBasicType.t_int );
decl = (IASTSimpleDeclaration) tu.getDeclarations()[2];
IFunction signal = (IFunction)decl.getDeclarators()[0].getName().resolveBinding();
IFunctionType signal_t = signal.getType();
IType signal_ret_1 = signal_t.getReturnType();
assertTrue( signal_ret_1 instanceof ITypedef );
IType signal_ret_2 = ((ITypedef)signal_ret_1).getType();
assertTrue( signal_ret_2 instanceof IPointerType );
IType signal_ret_3 = ((IPointerType)signal_ret_2).getType();
assertTrue( signal_ret_3 instanceof IFunctionType );
IType signal_ret_ret_1 = ((IFunctionType)signal_ret_3).getReturnType();
assertTrue( signal_ret_ret_1 instanceof ITypedef );
IType signal_ret_ret_2 = ((ITypedef)signal_ret_ret_1).getType();
assertTrue( signal_ret_ret_2 instanceof IBasicType );
assertEquals( ((IBasicType)signal_ret_ret_2).getType(), IBasicType.t_void );
assertTrue( ((ITypedef)signal_ret_ret_1).getName().equals("DWORD") ); //$NON-NLS-1$
IType signal_parm_t1 = signal_t.getParameterTypes()[0];
assertTrue( signal_parm_t1 instanceof IBasicType );
assertEquals( ((IBasicType)signal_parm_t1).getType(), IBasicType.t_int );
IType signal_parm_t2 = signal_t.getParameterTypes()[1];
assertTrue( signal_parm_t2 instanceof ITypedef );
IType signal_parm_t2_1 = ((ITypedef)signal_parm_t2).getType();
assertTrue( signal_parm_t2_1 instanceof IPointerType );
IType signal_parm_t2_2 = ((IPointerType)signal_parm_t2_1).getType();
assertTrue( signal_parm_t2_2 instanceof IFunctionType );
IType signal_parm_t2_ret_1 = ((IFunctionType)signal_parm_t2_2).getReturnType();
assertTrue( signal_parm_t2_ret_1 instanceof ITypedef );
IType signal_parm_t2_ret_2 = ((ITypedef)signal_parm_t2_ret_1).getType();
assertTrue( signal_parm_t2_ret_2 instanceof IBasicType );
assertEquals( ((IBasicType)signal_parm_t2_ret_2).getType(), IBasicType.t_void );
assertTrue( ((ITypedef)signal_parm_t2_ret_1).getName().equals("DWORD") ); //$NON-NLS-1$
}
public void testTypedefExample4c() throws Exception {
StringBuffer buffer = new StringBuffer( "typedef void fv(int), (*pfv)(int);\n" ); //$NON-NLS-1$
buffer.append( "void (*signal1(int, void (*)(int)))(int);\n" ); //$NON-NLS-1$
buffer.append( "fv *signal2(int, fv *);\n" ); //$NON-NLS-1$
buffer.append( "pfv signal3(int, pfv);\n" ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C );
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0];
ITypedef fv = (ITypedef)decl.getDeclarators()[0].getName().resolveBinding();
ITypedef pfv = (ITypedef)decl.getDeclarators()[1].getNestedDeclarator().getName().resolveBinding();
IType fv_t = fv.getType();
assertEquals( ((IBasicType)((IFunctionType)fv_t).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)fv_t).getParameterTypes()[0]).getType(), IBasicType.t_int );
IType pfv_t = pfv.getType();
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)pfv_t).getType()).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)pfv.getType()).getType()).getParameterTypes()[0]).getType(), IBasicType.t_int );
decl = (IASTSimpleDeclaration)tu.getDeclarations()[1];
IFunction signal1 = (IFunction)decl.getDeclarators()[0].getNestedDeclarator().getName().resolveBinding();
IType signal1_t = signal1.getType();
decl = (IASTSimpleDeclaration)tu.getDeclarations()[2];
IFunction signal2 = (IFunction)decl.getDeclarators()[0].getName().resolveBinding();
IType signal2_t = signal2.getType();
decl = (IASTSimpleDeclaration)tu.getDeclarations()[3];
IFunction signal3 = (IFunction)decl.getDeclarators()[0].getName().resolveBinding();
IType signal3_t = signal3.getType();
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)((IFunctionType)signal1_t).getReturnType()).getType()).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)signal1_t).getParameterTypes()[0]).getType(), IBasicType.t_int );
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)((IFunctionType)signal1_t).getParameterTypes()[1]).getType()).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)((IFunctionType)signal1_t).getParameterTypes()[1]).getType()).getParameterTypes()[0]).getType(), IBasicType.t_int );
assertEquals( ((IBasicType)((IFunctionType)((ITypedef)((IPointerType)((IFunctionType)signal2_t).getReturnType()).getType()).getType()).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)signal2_t).getParameterTypes()[0]).getType(), IBasicType.t_int );
assertEquals( ((IBasicType)((IFunctionType)((ITypedef)((IPointerType)((IFunctionType)signal2_t).getParameterTypes()[1]).getType()).getType()).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)((ITypedef)((IPointerType)((IFunctionType)signal2_t).getParameterTypes()[1]).getType()).getType()).getParameterTypes()[0]).getType(), IBasicType.t_int );
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)((ITypedef)((IFunctionType)signal3_t).getReturnType()).getType()).getType()).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)signal3_t).getParameterTypes()[0]).getType(), IBasicType.t_int );
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)((ITypedef)((IFunctionType)signal3_t).getParameterTypes()[1]).getType()).getType()).getReturnType()).getType(), IBasicType.t_void );
assertEquals( ((IBasicType)((IFunctionType)((IPointerType)((ITypedef)((IFunctionType)signal3_t).getParameterTypes()[1]).getType()).getType()).getParameterTypes()[0]).getType(), IBasicType.t_int );
}
}

View file

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
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.IASTNode;
@ -22,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
/**
* Created on Nov 5, 2004
@ -128,8 +130,14 @@ public class CFunction implements IFunction {
*/
public IFunctionType getType() {
if( type == null ) {
IASTFunctionDeclarator functionName = ( definition != null ) ? definition : declarators[0];
type = CVisitor.createFunctionType( functionName );
IASTDeclarator functionName = ( definition != null ) ? definition : declarators[0];
while (functionName.getName().toString() == null)
functionName = functionName.getNestedDeclarator();
IType tempType = CVisitor.createType( functionName.getName() );
if (tempType instanceof IFunctionType)
type = (IFunctionType)tempType;
}
return type;

View file

@ -255,7 +255,7 @@ public class CVisitor {
if( binding != null )
((CFunction)binding).addDeclarator( (IASTFunctionDeclarator) declarator );
else
binding = new CFunction( (IASTFunctionDeclarator) declarator );
binding = createBinding(declarator);
} else if( parent instanceof IASTSimpleDeclaration ){
binding = createBinding( (IASTSimpleDeclaration) parent, name );
} else if( parent instanceof IASTParameterDeclaration ){
@ -294,7 +294,10 @@ public class CVisitor {
}
}
binding = new CFunction( (IASTFunctionDeclarator) declarator );
if( parent instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration) parent).getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef)
binding = new CTypeDef( declarator.getName() );
else
binding = new CFunction( (IASTFunctionDeclarator) declarator );
} else if( parent instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent;
if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){
@ -931,33 +934,84 @@ public class CVisitor {
return true;
}
/**
* Create an IType for an IASTName.
*
* @param name the IASTName whose IType will be created
* @return the IType of the IASTName parameter
*/
public static IType createType(IASTName name) {
return createType(name, false);
}
/**
* This method is used to create the structure of ITypes based on the structure of the IASTDeclarator for the IASTName pased in.
*
* This method has recursive behaviour if the IASTDeclarator's parent is found to be an IASTFunctionDeclarator.
* Recursion is used to get the IType of the IASTDeclarator's parent.
*
* If the IASTDeclarator's parent is an IASTSimpleDeclaration, an IASTFunctionDefinition, or an IASTParameterDeclaration then
* any recurisve behaviour to that point is stopped and the proper IType is returned at that point.
*
* @param name the IASTName to create an IType for
* @param isParm whether the IASTName is a parameter in a declaration or not
* @return the IType corresponding to the IASTName
*/
public static IType createType(IASTName name, boolean isParm) {
// if it's not a declarator then return null, otherwise work with its parent
if (!(name.getParent() instanceof IASTDeclarator)) return null;
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
if (declarator.getParent() instanceof IASTSimpleDeclaration) {
return createBaseType( declarator, ((IASTSimpleDeclaration)(declarator).getParent()).getDeclSpecifier(), isParm );
// if it's a simple declaration then create a base type and a function type if necessary and return it
if (declarator.getParent() instanceof IASTSimpleDeclaration) {
IType lastType = createBaseType( declarator, ((IASTSimpleDeclaration)declarator.getParent()).getDeclSpecifier(), isParm );
if (declarator instanceof IASTFunctionDeclarator)
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
return lastType;
// if it's a function declarator then use recursion to get the parent's type
} else if (declarator.getParent() instanceof IASTFunctionDeclarator) {
IASTDeclarator origDecltor = (IASTDeclarator)declarator.getParent();
IType returnType = createType(origDecltor.getName(), isParm);
IType lastType = new CFunctionType(returnType, getParmTypes((IASTFunctionDeclarator)declarator.getParent()));
IType lastType = createType(origDecltor.getName(), isParm); // use recursion to get the type of the IASTDeclarator's parent
// if it was a function declarator and its parent is a function definition then do cleanup from the recursion here (setup pointers/arrays/and get functiontype)
if (declarator.getParent().getParent() instanceof IASTFunctionDefinition) {
if (declarator.getPointerOperators() != IASTDeclarator.EMPTY_DECLARATOR_ARRAY)
lastType = setupPointerChain(declarator.getPointerOperators(), lastType);
IType arrayChain = setupArrayChain(declarator, lastType);
if (arrayChain != null) lastType = arrayChain;
if (declarator.getPointerOperators() != null)
lastType = setupPointerChain(declarator.getPointerOperators(), lastType);
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
// if it was a function declarator and its parent is not a function definition then do cleanup from the recursion here (setup pointers/arrays/ and check if need function type)
} else {
if (declarator.getPointerOperators() != IASTDeclarator.EMPTY_DECLARATOR_ARRAY)
lastType = setupPointerChain(declarator.getPointerOperators(), lastType);
IType arrayChain = setupArrayChain(declarator, lastType);
if (arrayChain != null) lastType = arrayChain;
if (declarator instanceof IASTFunctionDeclarator)
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
}
IType arrayChain = setupArrayChain(declarator, lastType);
if (arrayChain != null) lastType = arrayChain;
return lastType;
// if it's a function definition then create the base type and setup a function type if necessary
} else if (declarator.getParent() instanceof IASTFunctionDefinition) {
IASTFunctionDefinition functionDef = (IASTFunctionDefinition)declarator.getParent();
return createBaseType(functionDef.getDeclarator(), functionDef.getDeclSpecifier(), isParm);
IType lastType = createBaseType(functionDef.getDeclarator(), functionDef.getDeclSpecifier(), isParm);
if (declarator instanceof IASTFunctionDeclarator)
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
return lastType;
// if it's a parameter declaration then setup the base type, if necessary setup a function type and change it's return type to pointer to function returning T
} else if (declarator.getParent() instanceof IASTParameterDeclaration) {
if (declarator instanceof IASTFunctionDeclarator) {
IType returnType = createBaseType(declarator, ((IASTParameterDeclaration)declarator.getParent()).getDeclSpecifier(), isParm);
@ -978,9 +1032,19 @@ public class CVisitor {
return createBaseType( declarator, ((IASTParameterDeclaration)(declarator).getParent()).getDeclSpecifier(), isParm );
}
return createType((IASTName)declarator.getParent());
return null; // if anything else isn't supported yet return null for now
}
/**
* This is used to create a base IType corresponding to an IASTDeclarator and the IASTDeclSpecifier. This method doesn't have any recursive
* behaviour and is used as the foundation of the ITypes being created.
* The parameter isParm is used to specify whether the declarator is a parameter or not.
*
* @param declarator the IASTDeclarator whose base IType will be created
* @param declSpec the IASTDeclSpecifier used to determine if the base type is a CQualifierType or not
* @param isParm is used to specify whether the IASTDeclarator is a parameter of a declaration
* @return the base IType
*/
public static IType createBaseType(IASTDeclarator declarator, IASTDeclSpecifier declSpec, boolean isParm) {
IType lastType = null;
@ -1056,6 +1120,31 @@ public class CVisitor {
return lastType;
}
/**
* Returns an IType[] corresponding to the parameter types of the IASTFunctionDeclarator parameter.
*
* @param decltor the IASTFunctionDeclarator to create an IType[] for its parameters
* @return IType[] corresponding to the IASTFunctionDeclarator parameters
*/
private static IType[] getParmTypes( IASTFunctionDeclarator decltor ){
IASTParameterDeclaration parms[] = decltor.getParameters();
IType parmTypes[] = new IType[parms.length];
for( int i = 0; i < parms.length; i++ ){
parmTypes[i] = createType(parms[i].getDeclarator().getName(), true);
}
return parmTypes;
}
/**
* Setup a chain of CQualifiedPointerType for the IASTArrayModifier[] of an IASTArrayDeclarator.
* The CQualifiedType is an IPointerType that is qualified with the IASTArrayModifier.
* i.e. the modifiers within the [ and ] of the array type
*
* @param decl the IASTDeclarator that is a parameter and has the IASTArrayModifier[]
* @param lastType the IType that the end of the CQualifiedPointerType chain points to
* @return the starting CQualifiedPointerType at the beginning of the CQualifiedPointerType chain
*/
private static IType setupArrayParmChain(IASTDeclarator decl, IType lastType) {
if (decl instanceof IASTArrayDeclarator) {
int i=0;
@ -1073,20 +1162,16 @@ public class CVisitor {
return null;
}
public static IFunctionType createFunctionType( IASTFunctionDeclarator functionName ) {
return new CFunctionType( CVisitor.createType(functionName.getName()), getParmTypes(functionName) );
}
private static IType[] getParmTypes( IASTFunctionDeclarator decltor ){
IASTParameterDeclaration parms[] = decltor.getParameters();
IType parmTypes[] = new IType[parms.length];
for( int i = 0; i < parms.length; i++ ){
parmTypes[i] = createType(parms[i].getDeclarator().getName(), true);
}
return parmTypes;
}
/**
* Traverse through an array of IASTArrayModifier[] corresponding to the IASTDeclarator decl parameter.
* For each IASTArrayModifier in the array, create a corresponding CArrayType object and
* link it in a chain. The returned IType is the start of the CArrayType chain that represents
* the types of the IASTArrayModifier objects in the declarator.
*
* @param decl the IASTDeclarator containing the IASTArrayModifier[] array to create a CArrayType chain for
* @param lastType the IType that the end of the CArrayType chain points to
* @return the starting CArrayType at the beginning of the CArrayType chain
*/
private static IType setupArrayChain(IASTDeclarator decl, IType lastType) {
if (decl instanceof IASTArrayDeclarator) {
int i=0;
@ -1108,6 +1193,14 @@ public class CVisitor {
return null;
}
/**
* Traverse through an array of IASTPointerOperator[] pointers and set up a pointer chain
* corresponding to the types of the IASTPointerOperator[].
*
* @param ptrs an array of IASTPointerOperator[] used to setup the pointer chain
* @param lastType the IType that the end of the CPointerType chain points to
* @return the starting CPointerType at the beginning of the CPointerType chain
*/
private static IType setupPointerChain(IASTPointerOperator[] ptrs, IType lastType) {
CPointerType pointerType = null;

View file

@ -1175,6 +1175,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IASTCompositeTypeSpecifier structSpec = null;
IASTElaboratedTypeSpecifier elabSpec = null;
IASTEnumerationSpecifier enumSpec = null;
boolean isTypedef = false;
declSpecifiers: for (;;) {
switch (LT(1)) {
@ -1196,6 +1197,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
consume();
break;
case IToken.t_typedef:
isTypedef = true;
storageClass = IASTDeclSpecifier.sc_typedef;
consume();
break;
@ -1299,8 +1301,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
switch( LT(2) )
{
case IToken.tLPAREN:
if (isTypedef) break;
case IToken.tSEMI:
case IToken.tLPAREN:
case IToken.tASSIGN:
//TODO more
break declSpecifiers;