From ee264718512cea98043bf7891f3a38fcf1e0aad2 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Tue, 21 Dec 2004 16:27:04 +0000 Subject: [PATCH] Patch for Devin Steffler. Fix for 108 Perrors in Dave's test associated with testTypedefExample4b (changes made to GNUCSourceParser) Better support for Function Types --- .../cdt/core/parser/tests/ast2/AST2Tests.java | 167 ++++++++++++++++++ .../internal/core/dom/parser/c/CFunction.java | 12 +- .../internal/core/dom/parser/c/CVisitor.java | 149 +++++++++++++--- .../core/dom/parser/c/GNUCSourceParser.java | 5 +- 4 files changed, 302 insertions(+), 31 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index d29edf673c4..ac5b88ca9b0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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 ); + + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java index ad5884f950b..0d358958819 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index 2eb0af973f5..a3ad9c1c6c8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 1667f55b649..1a5b50c5f31 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -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;