diff options
author | John Camelon | 2004-12-17 20:23:47 +0000 |
---|---|---|
committer | John Camelon | 2004-12-17 20:23:47 +0000 |
commit | 0cb94d4f49b1458380be1321fe338320c647baa9 (patch) | |
tree | d1e0c2c4fe3d8e477528c25f8d900db8f502436b /core | |
parent | ec4d154f1300d35ad9d0ef522fe35e86760c7801 (diff) | |
download | org.eclipse.cdt-0cb94d4f49b1458380be1321fe338320c647baa9.tar.gz org.eclipse.cdt-0cb94d4f49b1458380be1321fe338320c647baa9.tar.xz org.eclipse.cdt-0cb94d4f49b1458380be1321fe338320c647baa9.zip |
Patch for Devin Steffler.
This patch adds the implementation of CFunctionTypes to the new parser. In it I also cleaned up some of the old implementation that I had for other types so that it was easier to implement FunctionTypes.
Diffstat (limited to 'core')
7 files changed, 369 insertions, 23 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 5898477ab65..d29edf673c4 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 @@ -12,6 +12,7 @@ package org.eclipse.cdt.core.parser.tests.ast2; import java.util.List; +import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; @@ -44,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; @@ -68,6 +70,8 @@ import org.eclipse.cdt.core.dom.ast.c.ICArrayType; import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionDeclarator; +import org.eclipse.cdt.internal.core.dom.parser.c.CFunction; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.parser.ParserException; @@ -1067,7 +1071,7 @@ public class AST2Tests extends AST2BaseTest { assertEquals( ((IBasicType)t_c_6).getType(), IBasicType.t_char); } - public void _testFunctionTypes() throws Exception{ + 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$ @@ -1118,7 +1122,7 @@ public class AST2Tests extends AST2BaseTest { 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_g_func.getReturnType(); + 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]; @@ -1166,5 +1170,79 @@ public class AST2Tests extends AST2BaseTest { assertNotNull( fieldDesignator.getName().toString() ); } } + + public void testFnReturningPtrToFn() throws Exception { + IASTTranslationUnit tu = parse( "void ( * f( int ) )(){}", ParserLanguage.C ); //$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 ); + } + + // test C99: 6.7.5.3-7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to + // type’’, where the type qualifiers (if any) are those specified within the [ and ] of the + // array type derivation. + public void testArrayTypeToQualifiedPointerTypeParm() throws Exception { + IASTTranslationUnit tu = parse( "void f(int parm[const 3]);", ParserLanguage.C ); //$NON-NLS-1$ + + IASTSimpleDeclaration def = (IASTSimpleDeclaration) tu.getDeclarations()[0]; + IFunction f = (IFunction) def.getDeclarators()[0].getName().resolveBinding(); + + IFunctionType ft = f.getType(); + assertTrue( ft.getParameterTypes()[0] instanceof IPointerType ); + assertTrue( ((IPointerType)ft.getParameterTypes()[0]).isConst() ); + } + + // 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$ + + IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[0]; + IFunction f = (IFunction) def.getDeclarator().getName().resolveBinding(); + + IType ft = ((CFunction)f).getType(); + assertTrue( ft instanceof IFunctionType ); + IType gt_1 = ((IFunctionType)ft).getParameterTypes()[0]; + assertTrue( gt_1 instanceof IPointerType ); + IType gt_2 = ((IPointerType)gt_1).getType(); + assertTrue( gt_2 instanceof IFunctionType ); + IType gt_ret = ((IFunctionType)gt_2).getReturnType(); + assertTrue( gt_ret instanceof IBasicType ); + assertEquals( ((IBasicType)gt_ret).getType(), IBasicType.t_int ); + IType gt_parm = ((IFunctionType)gt_2).getParameterTypes()[0]; + assertTrue( gt_parm instanceof IBasicType ); + assertEquals( ((IBasicType)gt_parm).getType(), IBasicType.t_void ); + } + + public void testArrayPointerFunction() throws Exception { + IASTTranslationUnit tu = parse( "int (*v[])(int *x, int *y);", ParserLanguage.C ); //$NON-NLS-1$ + + IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0]; + IVariable v = (IVariable)((IASTFunctionDeclarator) decl.getDeclarators()[0]).getNestedDeclarator().getName().resolveBinding(); + + IType vt_1 = v.getType(); + assertTrue( vt_1 instanceof IArrayType ); + IType vt_2 = ((IArrayType)vt_1).getType(); + assertTrue( vt_2 instanceof IPointerType ); + IType vt_3 = ((IPointerType)vt_2).getType(); + assertTrue( vt_3 instanceof IFunctionType ); + IType vt_ret = ((IFunctionType)vt_3).getReturnType(); + assertTrue( vt_ret instanceof IBasicType ); + assertEquals( ((IBasicType)vt_ret).getType(), IBasicType.t_int ); + assertEquals( ((IFunctionType)vt_3).getParameterTypes().length, 2 ); + IType vpt_1 = ((IFunctionType)vt_3).getParameterTypes()[0]; + assertTrue( vpt_1 instanceof IPointerType ); + IType vpt_1_2 = ((IPointerType)vpt_1).getType(); + assertTrue( vpt_1_2 instanceof IBasicType ); + assertEquals( ((IBasicType)vpt_1_2).getType(), IBasicType.t_int ); + IType vpt_2 = ((IFunctionType)vt_3).getParameterTypes()[0]; + assertTrue( vpt_2 instanceof IPointerType ); + IType vpt_2_2 = ((IPointerType)vpt_1).getType(); + assertTrue( vpt_2_2 instanceof IBasicType ); + assertEquals( ((IBasicType)vpt_2_2).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 9b054462852..ad5884f950b 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 @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IScope; public class CFunction implements IFunction { private IASTFunctionDeclarator [] declarators = null; private IASTFunctionDeclarator definition; + IFunctionType type = null; public CFunction( IASTFunctionDeclarator declarator ){ if( declarator.getParent() instanceof IASTFunctionDefinition ) @@ -126,8 +127,12 @@ public class CFunction implements IFunction { * @see org.eclipse.cdt.core.dom.ast.IFunction#getType() */ public IFunctionType getType() { - // TODO Auto-generated method stub - return null; + if( type == null ) { + IASTFunctionDeclarator functionName = ( definition != null ) ? definition : declarators[0]; + type = CVisitor.createFunctionType( functionName ); + } + + return type; } // public IASTDeclaration getDeclaration(){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunctionType.java new file mode 100644 index 00000000000..ee159f88d2d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunctionType.java @@ -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 + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.c; + +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IType; + +/** + * @author dsteffle + */ +public class CFunctionType implements IFunctionType { + IType[] parameters = null; + IType returnType = null; + + /** + * @param returnType + * @param types + */ + public CFunctionType( IType returnType, IType [] types ) { + this.returnType = returnType; + this.parameters = types; + } + + public boolean equals( Object o ){ + if( o instanceof IFunctionType ){ + IFunctionType ft = (IFunctionType) o; + IType [] fps = ft.getParameterTypes(); + + if( fps.length != parameters.length ) + return false; + if( ! returnType.equals( ft.getReturnType() ) ) + return false; + for( int i = 0; i < parameters.length; i++ ) + if( ! parameters[i].equals( fps[i] ) ) + return false; + return true; + } + return false; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunctionType#getReturnType() + */ + public IType getReturnType() { + return returnType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunctionType#getParameterTypes() + */ + public IType[] getParameterTypes() { + return parameters; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifiedPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifiedPointerType.java new file mode 100644 index 00000000000..db88f8b11ff --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifiedPointerType.java @@ -0,0 +1,65 @@ +/********************************************************************** + * Copyright (c) 2002-2004 IBM Canada 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: + * IBM Rational Software - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.c; + +import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier; +import org.eclipse.cdt.core.dom.ast.c.ICPointerType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; + +/** + * @author dsteffle + */ +public class CQualifiedPointerType implements ICPointerType, ITypeContainer { + IType nextType = null; + IASTArrayModifier mod = null; + + public CQualifiedPointerType(IType next, IASTArrayModifier mod) { + this.nextType = next; + if (mod instanceof ICASTArrayModifier) this.mod = mod; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.c.ICPointerType#isRestrict() + */ + public boolean isRestrict() { + if (mod == null || !(mod instanceof ICASTArrayModifier)) return false; + return ((ICASTArrayModifier)mod).isRestrict(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IPointerType#getType() + */ + public IType getType() { + return nextType; + } + + public void setType(IType type) { + nextType = type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IPointerType#isConst() + */ + public boolean isConst() { + if (mod == null || !(mod instanceof ICASTArrayModifier)) return false; + return ((ICASTArrayModifier)mod).isConst(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IPointerType#isVolatile() + */ + public boolean isVolatile() { + if (mod == null || !(mod instanceof ICASTArrayModifier)) return false; + return ((ICASTArrayModifier)mod).isVolatile(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java index dfa5570664d..731f0a08ba8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java @@ -40,7 +40,7 @@ public class CTypeDef implements ITypedef, ITypeContainer { */ public IType getType() { if (type == null) - type = CVisitor.getType(name); + type = CVisitor.createType(name); return type; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java index cfeef046d66..c3c30221ae0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java @@ -59,7 +59,7 @@ public class CVariable implements IVariable { */ public IType getType() { if (type == null) - type = CVisitor.getType(name); + type = CVisitor.createType(name); 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 2368e1d1f3b..2eb0af973f5 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 @@ -62,6 +62,7 @@ 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.IFunction; +import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; @@ -259,11 +260,58 @@ public class CVisitor { binding = createBinding( (IASTSimpleDeclaration) parent, name ); } else if( parent instanceof IASTParameterDeclaration ){ binding = createBinding( (IASTParameterDeclaration ) parent ); + } else if ( parent instanceof IASTFunctionDeclarator ) { + binding = createBinding(declarator); } return binding; } + private static IBinding createBinding( IASTDeclarator declarator ){ + IASTNode parent = declarator.getParent(); + + if( declarator.getNestedDeclarator() != null ) + return createBinding( declarator.getNestedDeclarator() ); + + while( parent instanceof IASTDeclarator ){ + parent = parent.getParent(); + } + + ICScope scope = (ICScope) getContainingScope( parent ); + IBinding binding = null; + binding = ( scope != null ) ? scope.getBinding( ICScope.NAMESPACE_TYPE_OTHER, declarator.getName().toCharArray() ) : null; + + if( declarator instanceof IASTFunctionDeclarator ){ + if( binding != null && binding instanceof IFunction ){ + IFunction function = (IFunction) binding; + IFunctionType ftype = function.getType(); + IType type = createType( declarator.getName() ); + if( ftype.equals( type ) ){ + if( parent instanceof IASTSimpleDeclaration ) + ((CFunction)function).addDeclarator( (IASTFunctionDeclarator) declarator ); + + return function; + } + } + + binding = new CFunction( (IASTFunctionDeclarator) declarator ); + } else if( parent instanceof IASTSimpleDeclaration ){ + IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent; + if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){ + binding = new CTypeDef( declarator.getName() ); + } else if( simpleDecl.getParent() instanceof ICASTCompositeTypeSpecifier ){ + binding = new CField( declarator.getName() ); + } else { + binding = new CVariable( declarator.getName() ); + } + } + + if( scope != null && binding != null ) + scope.addBinding( binding ); + return binding; + } + + private static IBinding createBinding( ICASTCompositeTypeSpecifier compositeTypeSpec ){ ICompositeType binding = new CStructure( compositeTypeSpec ); ICScope scope = (ICScope) binding.getScope(); @@ -883,58 +931,111 @@ public class CVisitor { return true; } - public static IType getType(IASTName name) { + public static IType createType(IASTName name) { + return createType(name, false); + } + + public static IType createType(IASTName name, boolean isParm) { + if (!(name.getParent() instanceof IASTDeclarator)) return null; + IASTDeclarator declarator = (IASTDeclarator) name.getParent(); - IASTSimpleDeclaration declaration = (IASTSimpleDeclaration) declarator.getParent(); - IASTDeclSpecifier declSpec = declaration.getDeclSpecifier(); + if (declarator.getParent() instanceof IASTSimpleDeclaration) { + return createBaseType( declarator, ((IASTSimpleDeclaration)(declarator).getParent()).getDeclSpecifier(), isParm ); + } 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())); + + if (declarator.getPointerOperators() != null) + lastType = setupPointerChain(declarator.getPointerOperators(), lastType); + + IType arrayChain = setupArrayChain(declarator, lastType); + if (arrayChain != null) lastType = arrayChain; + + return lastType; + } else if (declarator.getParent() instanceof IASTFunctionDefinition) { + IASTFunctionDefinition functionDef = (IASTFunctionDefinition)declarator.getParent(); + + return createBaseType(functionDef.getDeclarator(), functionDef.getDeclSpecifier(), isParm); + } else if (declarator.getParent() instanceof IASTParameterDeclaration) { + if (declarator instanceof IASTFunctionDeclarator) { + IType returnType = createBaseType(declarator, ((IASTParameterDeclaration)declarator.getParent()).getDeclSpecifier(), isParm); + IType lastType = new CFunctionType(returnType, getParmTypes((IASTFunctionDeclarator)declarator)); + + if (declarator.getPointerOperators() != IASTPointerOperator.EMPTY_ARRAY) + lastType = setupPointerChain(declarator.getPointerOperators(), lastType); + + IType arrayChain = setupArrayChain(declarator, lastType); + if (arrayChain != null) lastType = arrayChain; + + // any parameter to type function returning T is adjusted to be pointer to function returning T + lastType = new CPointerType( lastType ); + + return lastType; + } + + return createBaseType( declarator, ((IASTParameterDeclaration)(declarator).getParent()).getDeclSpecifier(), isParm ); + } + + return createType((IASTName)declarator.getParent()); + } + + public static IType createBaseType(IASTDeclarator declarator, IASTDeclSpecifier declSpec, boolean isParm) { + IType lastType = null; + if( declSpec instanceof ICASTTypedefNameSpecifier ){ if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict())) return new CQualifierType(declSpec); - IType lastType = null; ICASTTypedefNameSpecifier nameSpec = (ICASTTypedefNameSpecifier) declSpec; lastType = (IType) nameSpec.getName().resolveBinding(); IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); if (pointerChain != null) lastType = pointerChain; - IType arrayChain = setupArrayChain(declarator, lastType); + IType arrayChain = null; + if (isParm) + arrayChain = setupArrayParmChain(declarator, lastType); + else + arrayChain = setupArrayChain(declarator, lastType); if (arrayChain != null) lastType = arrayChain; - return lastType; } else if( declSpec instanceof IASTElaboratedTypeSpecifier ){ if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict())) return new CQualifierType(declSpec); - IType lastType = null; IASTElaboratedTypeSpecifier elabTypeSpec = (IASTElaboratedTypeSpecifier) declSpec; lastType = (IType) elabTypeSpec.getName().resolveBinding(); IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); if (pointerChain != null) lastType = pointerChain; - IType arrayChain = setupArrayChain(declarator, lastType); + IType arrayChain = null; + if (isParm) + arrayChain = setupArrayParmChain(declarator, lastType); + else + arrayChain = setupArrayChain(declarator, lastType); if (arrayChain != null) lastType = arrayChain; - return lastType; } else if( declSpec instanceof IASTCompositeTypeSpecifier ){ if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict())) return new CQualifierType(declSpec); - IType lastType = null; IASTCompositeTypeSpecifier compTypeSpec = (IASTCompositeTypeSpecifier) declSpec; lastType = (IType) compTypeSpec.getName().resolveBinding(); IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); if (pointerChain != null) lastType = pointerChain; - IType arrayChain = setupArrayChain(declarator, lastType); + IType arrayChain = null; + if (isParm) + arrayChain = setupArrayParmChain(declarator, lastType); + else + arrayChain = setupArrayChain(declarator, lastType); if (arrayChain != null) lastType = arrayChain; - return lastType; } else if (declSpec instanceof ICASTSimpleDeclSpecifier) { - IType lastType = null; if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict())) lastType = new CQualifierType(declSpec); else @@ -943,14 +1044,49 @@ public class CVisitor { IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); if (pointerChain != null) lastType = pointerChain; - IType arrayChain = setupArrayChain(declarator, lastType); + IType arrayChain = null; + if (isParm) + arrayChain = setupArrayParmChain(declarator, lastType); + else + arrayChain = setupArrayChain(declarator, lastType); if (arrayChain != null) lastType = arrayChain; - return lastType; } + + return lastType; + } + + private static IType setupArrayParmChain(IASTDeclarator decl, IType lastType) { + if (decl instanceof IASTArrayDeclarator) { + int i=0; + IASTArrayModifier[] mods = ((IASTArrayDeclarator)decl).getArrayModifiers(); + + // C99: 6.7.5.3-7 "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) + // are those specified within the [ and ] of the array type derivation + IType pType = new CQualifiedPointerType(lastType, mods[i++]); + for (; i < ((IASTArrayDeclarator)decl).getArrayModifiers().length - 1; i++) { + pType = new CQualifiedPointerType(lastType, mods[i]); + } + return pType; + } + 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; + } + private static IType setupArrayChain(IASTDeclarator decl, IType lastType) { if (decl instanceof IASTArrayDeclarator) { int i=0; @@ -958,7 +1094,7 @@ public class CVisitor { CArrayType arrayType = new CArrayType(lastType); if (mods[i] instanceof ICASTArrayModifier) { - arrayType.setModifiedArrayModifier((ICASTArrayModifier)mods[i]); + arrayType.setModifiedArrayModifier((ICASTArrayModifier)mods[i++]); } for (; i < ((IASTArrayDeclarator)decl).getArrayModifiers().length - 1; i++) { arrayType = new CArrayType(arrayType); |