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 29e9906bf98..038ae573188 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 @@ -39,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; @@ -58,6 +59,7 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTPointer; +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; @@ -1011,6 +1013,55 @@ public class AST2Tests extends AST2BaseTest { assertSame( ((IPointerType) t_AP).getType(), A ); } + public void testArrayTypes() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "int a[restrict]; \n" ); //$NON-NLS-1$ + buffer.append( "char * b[][]; \n" ); //$NON-NLS-1$ + buffer.append( "const char * const c[][][]; \n" ); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + + IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0]; + IVariable a = (IVariable) decl.getDeclarators()[0].getName().resolveBinding(); + decl = (IASTSimpleDeclaration) tu.getDeclarations()[1]; + IVariable b = (IVariable) decl.getDeclarators()[0].getName().resolveBinding(); + decl = (IASTSimpleDeclaration) tu.getDeclarations()[2]; + IVariable c = (IVariable) decl.getDeclarators()[0].getName().resolveBinding(); + + IType t_a_1 = a.getType(); + assertTrue( t_a_1 instanceof ICArrayType ); + assertTrue( ((ICArrayType)t_a_1).isRestrict() ); + IType t_a_2 = ((IArrayType)t_a_1).getType(); + assertTrue( t_a_2 instanceof IBasicType ); + assertEquals( ((IBasicType)t_a_2).getType(), IBasicType.t_int ); + + IType t_b_1 = b.getType(); + assertTrue( t_b_1 instanceof IArrayType ); + IType t_b_2 = ((IArrayType)t_b_1).getType(); + assertTrue( t_b_2 instanceof IArrayType ); + IType t_b_3 = ((IArrayType)t_b_2).getType(); + assertTrue( t_b_3 instanceof IPointerType); + IType t_b_4 = ((IPointerType)t_b_3).getType(); + assertTrue( t_b_4 instanceof IBasicType); + assertEquals( ((IBasicType)t_b_4).getType(), IBasicType.t_char ); + + IType t_c_1 = c.getType(); + assertTrue( t_c_1 instanceof IArrayType ); + IType t_c_2 = ((IArrayType)t_c_1).getType(); + assertTrue( t_c_2 instanceof IArrayType ); + IType t_c_3 = ((IArrayType)t_c_2).getType(); + assertTrue( t_c_3 instanceof IArrayType ); + IType t_c_4 = ((IArrayType)t_c_3).getType(); + assertTrue( t_c_4 instanceof IPointerType ); + assertTrue( ((IPointerType)t_c_4).isConst()); + IType t_c_5 = ((IPointerType)t_c_4).getType(); + assertTrue( t_c_5 instanceof IQualifierType ); + assertTrue( ((IQualifierType)t_c_5).isConst()); + IType t_c_6 = ((IQualifierType)t_c_5).getType(); + assertTrue( t_c_6 instanceof IBasicType ); + assertEquals( ((IBasicType)t_c_6).getType(), IBasicType.t_char); + } + public void _testFunctionTypes() throws Exception{ StringBuffer buffer = new StringBuffer(); buffer.append( "struct A; \n"); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTypeContainer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICArrayType.java similarity index 63% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTypeContainer.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICArrayType.java index 3583b27081c..00be8dae734 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTypeContainer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICArrayType.java @@ -8,17 +8,17 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.c; -/* - * Created on Dec 13, 2004 - */ -package org.eclipse.cdt.internal.core.dom.parser.cpp; - -import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IArrayType; /** - * @author aniefer + * @author dsteffle */ -public interface ICPPTypeContainer extends IType{ - IType getType(); +public interface ICArrayType extends IArrayType { + public boolean isConst(); + public boolean isRestrict(); + public boolean isVolatile(); + public boolean isStatic(); + public boolean isVariableLength(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java new file mode 100644 index 00000000000..12e030620c9 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * 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.IType; +import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier; +import org.eclipse.cdt.core.dom.ast.c.ICArrayType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; + +/** + * @author dsteffle + */ +public class CArrayType implements ICArrayType, ITypeContainer { + + IType type = null; + ICASTArrayModifier mod = null; + + public CArrayType(IType type) { + this.type = type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IArrayType#getType() + */ + public IType getType() { + return type; + } + + public void setModifiedArrayModifier(ICASTArrayModifier mod) { + this.mod = mod; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.c.ICArrayType#isConst() + */ + public boolean isConst() { + if (mod==null) return false; + return mod.isConst(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.c.ICArrayType#isRestrict() + */ + public boolean isRestrict() { + if (mod==null) return false; + return mod.isRestrict(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.c.ICArrayType#isVolatile() + */ + public boolean isVolatile() { + if (mod==null) return false; + return mod.isVolatile(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.c.ICArrayType#isStatic() + */ + public boolean isStatic() { + if (mod==null) return false; + return mod.isStatic(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.c.ICArrayType#isVariableLength() + */ + public boolean isVariableLength() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java index 7bb6ac59a09..d6af183ef72 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java @@ -13,11 +13,12 @@ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.c.ICASTPointer; import org.eclipse.cdt.core.dom.ast.c.ICPointerType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * @author dsteffle */ -public class CPointerType implements ICPointerType { +public class CPointerType implements ICPointerType, ITypeContainer { IType nextType = null; ICASTPointer pointer = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java index f026fb877cf..0e84fff8c79 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java @@ -18,11 +18,12 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICQualifierType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * @author dsteffle */ -public class CQualifierType implements ICQualifierType { +public class CQualifierType implements ICQualifierType, ITypeContainer { IASTDeclSpecifier declSpec = null; IType type = null; @@ -74,9 +75,9 @@ public class CQualifierType implements ICQualifierType { } else if( declSpec instanceof IASTCompositeTypeSpecifier ){ IASTCompositeTypeSpecifier compTypeSpec = (IASTCompositeTypeSpecifier) declSpec; type = (IType) compTypeSpec.getName().resolveBinding(); - } - - type = new CBasicType((ICASTSimpleDeclSpecifier)declSpec); + } else { + type = new CBasicType((ICASTSimpleDeclSpecifier)declSpec); + } } return type; 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 ccf5f589a33..dfa5570664d 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 @@ -18,12 +18,13 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * Created on Nov 8, 2004 * @author aniefer */ -public class CTypeDef implements ITypedef { +public class CTypeDef implements ITypedef, ITypeContainer { private final IASTName name; private IType type = null; 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 0a0c66f0560..2368e1d1f3b 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 @@ -13,6 +13,8 @@ package org.eclipse.cdt.internal.core.dom.parser.c; import java.util.List; +import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; @@ -63,9 +65,9 @@ import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; +import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier; @@ -75,10 +77,10 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; -import org.eclipse.cdt.core.dom.ast.c.ICPointerType; import org.eclipse.cdt.core.dom.ast.c.ICScope; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * Created on Nov 5, 2004 @@ -215,12 +217,8 @@ public class CVisitor { } else { type = getExpressionType( fieldOwner ); } - while( type != null && (type instanceof ITypedef || type instanceof ICPointerType)) { - if (type instanceof ITypedef) { - type = ((ITypedef)type).getType(); - } else if (type instanceof ICPointerType) { - type = ((ICPointerType)type).getType(); - } + while( type != null && type instanceof ITypeContainer) { + type = ((ITypeContainer)type).getType(); } if( type != null && type instanceof ICompositeType ){ @@ -899,8 +897,10 @@ public class CVisitor { lastType = (IType) nameSpec.getName().resolveBinding(); IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); - - if (pointerChain != null) return pointerChain; + if (pointerChain != null) lastType = pointerChain; + + IType arrayChain = setupArrayChain(declarator, lastType); + if (arrayChain != null) lastType = arrayChain; return lastType; } else if( declSpec instanceof IASTElaboratedTypeSpecifier ){ @@ -912,8 +912,10 @@ public class CVisitor { lastType = (IType) elabTypeSpec.getName().resolveBinding(); IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); - - if (pointerChain != null) return pointerChain; + if (pointerChain != null) lastType = pointerChain; + + IType arrayChain = setupArrayChain(declarator, lastType); + if (arrayChain != null) lastType = arrayChain; return lastType; } else if( declSpec instanceof IASTCompositeTypeSpecifier ){ @@ -925,8 +927,10 @@ public class CVisitor { lastType = (IType) compTypeSpec.getName().resolveBinding(); IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); - - if (pointerChain != null) return pointerChain; + if (pointerChain != null) lastType = pointerChain; + + IType arrayChain = setupArrayChain(declarator, lastType); + if (arrayChain != null) lastType = arrayChain; return lastType; } else if (declSpec instanceof ICASTSimpleDeclSpecifier) { @@ -937,13 +941,36 @@ public class CVisitor { lastType = new CBasicType((ICASTSimpleDeclSpecifier)declSpec); IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType); - - if (pointerChain != null) return pointerChain; - + if (pointerChain != null) lastType = pointerChain; + + IType arrayChain = setupArrayChain(declarator, lastType); + if (arrayChain != null) lastType = arrayChain; + return lastType; } return null; } + + private static IType setupArrayChain(IASTDeclarator decl, IType lastType) { + if (decl instanceof IASTArrayDeclarator) { + int i=0; + IASTArrayModifier[] mods = ((IASTArrayDeclarator)decl).getArrayModifiers(); + + CArrayType arrayType = new CArrayType(lastType); + if (mods[i] instanceof ICASTArrayModifier) { + arrayType.setModifiedArrayModifier((ICASTArrayModifier)mods[i]); + } + for (; i < ((IASTArrayDeclarator)decl).getArrayModifiers().length - 1; i++) { + arrayType = new CArrayType(arrayType); + if (mods[i] instanceof ICASTArrayModifier) { + arrayType.setModifiedArrayModifier((ICASTArrayModifier)mods[i]); + } + } + return arrayType; + } + + return null; + } 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/cpp/CPPArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java index 94d73db14cc..5229354eb74 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java @@ -16,11 +16,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * @author aniefer */ -public class CPPArrayType implements IArrayType, ICPPTypeContainer { +public class CPPArrayType implements IArrayType, ITypeContainer { private IType type = null; public CPPArrayType( IType type ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java index c355add5443..2b577cc1679 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java @@ -16,11 +16,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTPointer; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * @author aniefer */ -public class CPPPointerType implements IPointerType, ICPPTypeContainer { +public class CPPPointerType implements IPointerType, ITypeContainer { private IASTPointer operator = null; private IType type = null; /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java index 09efd937c80..13485c52020 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java @@ -16,11 +16,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * @author aniefer */ -public class CPPQualifierType implements IQualifierType, ICPPTypeContainer { +public class CPPQualifierType implements IQualifierType, ITypeContainer { private boolean isConst = false; private boolean isVolatile = false; private IType type = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java index 8c73b755bc3..4125e0c2e0d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java @@ -19,11 +19,12 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * @author aniefer */ -public class CPPTypedef implements ITypedef, ICPPTypeContainer { +public class CPPTypedef implements ITypedef, ITypeContainer { private IASTDeclarator declarator = null; /** * @param declarator