From c885f752dad9daa1ee03dd2a57f8a759722c0252 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Thu, 19 May 2005 18:41:55 +0000 Subject: [PATCH] - types of expressions in C bug 95858 - typeof( exp ) as declspecifier in C bug 93980 --- .../cdt/core/parser/tests/ast2/AST2Tests.java | 19 +++ .../ast/gnu/c/IGCCASTSimpleDeclSpecifier.java | 40 ++++++ .../core/dom/parser/c/CBasicType.java | 46 ++++-- .../core/dom/parser/c/CQualifierType.java | 62 ++++---- .../internal/core/dom/parser/c/CVisitor.java | 133 +++++++++++++++++- .../parser/c/GCCASTSimpleDeclSpecifier.java | 64 +++++++++ .../core/dom/parser/c/GNUCSourceParser.java | 26 +++- .../core/dom/parser/cpp/CPPVisitor.java | 16 ++- .../dom/parser/cpp/GNUCPPSourceParser.java | 10 +- 9 files changed, 365 insertions(+), 51 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/IGCCASTSimpleDeclSpecifier.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCASTSimpleDeclSpecifier.java 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 038b738a20d..cc4ca7c3af8 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 @@ -3079,4 +3079,23 @@ public class AST2Tests extends AST2BaseTest { buffer.append("int function(TYPE (* pfv)(int parm));\n"); //$NON-NLS-1$ IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); } + + public void testBug93980() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("int foo(); \n"); //$NON-NLS-1$ + buffer.append("typeof({ int x = foo(); \n"); //$NON-NLS-1$ + buffer.append(" x; }) zoot; \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C, true); + CNameCollector col = new CNameCollector(); + tu.accept(col); + + IFunction foo = (IFunction) col.getName(0).resolveBinding(); + assertSame( foo, col.getName(2).resolveBinding() ); + + IVariable zoot = (IVariable) col.getName(4).resolveBinding(); + IType t = zoot.getType(); + assertTrue( t instanceof IBasicType ); + assertEquals( ((IBasicType)t).getType(), IBasicType.t_int ); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/IGCCASTSimpleDeclSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/IGCCASTSimpleDeclSpecifier.java new file mode 100644 index 00000000000..6cb714ef8d1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/IGCCASTSimpleDeclSpecifier.java @@ -0,0 +1,40 @@ +package org.eclipse.cdt.core.dom.ast.gnu.c; + +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier; + +public interface IGCCASTSimpleDeclSpecifier extends ICASTSimpleDeclSpecifier { + + /** + * t_typeof represents a typeof() expression type. + */ + public static final int t_typeof = ICASTSimpleDeclSpecifier.t_last + 1; + + /** + * t_last is specified for subinterfaces. + */ + public static final int t_last = t_typeof; + + /** + * TYPEOF_EXPRESSION represents the relationship between the + * decl spec & the expression for typeof(). + */ + public static final ASTNodeProperty TYPEOF_EXPRESSION = new ASTNodeProperty( + "IGCCASTSimpleDeclSpecifier.TYPEOF_EXPRESSION - typeof() Expression"); //$NON-NLS-1$ + + /** + * Set the typeof() expression. + * + * @param typeofExpression + * IASTExpression + */ + public void setTypeofExpression(IASTExpression typeofExpression); + + /** + * Get the typeof expression. + * + * @return IASTExpression + */ + public IASTExpression getTypeofExpression(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java index 119516d1ba4..7cd6f060125 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java @@ -20,8 +20,15 @@ import org.eclipse.cdt.core.dom.ast.c.ICBasicType; * @author dsteffle */ public class CBasicType implements ICBasicType { + static public final int IS_LONG = 1; + static public final int IS_LONGLONG = 1 << 1; + static public final int IS_SHORT = 1 << 2; + static public final int IS_SIGNED = 1 << 3; + static public final int IS_UNSIGNED = 1 << 4; - private ICASTSimpleDeclSpecifier sds = null; + private int type = 0; + private int qualifiers = 0; + private IASTExpression value = null; /** * keep a reference to the declaration specifier so that duplicate information isn't generated. @@ -29,46 +36,62 @@ public class CBasicType implements ICBasicType { * @param sds the simple declaration specifier */ public CBasicType(ICASTSimpleDeclSpecifier sds) { - this.sds = sds; + this.type = sds.getType(); + this.qualifiers = ( sds.isLong() ? CBasicType.IS_LONG : 0 ) | + ( sds.isShort() ? CBasicType.IS_SHORT : 0 ) | + ( sds.isSigned() ? CBasicType.IS_SIGNED: 0 ) | + ( sds.isUnsigned()? CBasicType.IS_UNSIGNED : 0 ) | + ( sds.isUnsigned()? CBasicType.IS_LONGLONG : 0 ); + } + + public CBasicType( int type, int qualifiers ){ + this.type = type; + this.qualifiers = qualifiers; + } + + public CBasicType( int type, int qualifiers, IASTExpression value ){ + this.type = type; + this.qualifiers = qualifiers; + this.value = value; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBasicType#getType() */ public int getType() { - return sds.getType(); + return type; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBasicType#isSigned() */ public boolean isSigned() { - return sds.isSigned(); + return ( qualifiers & IS_SIGNED) != 0; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBasicType#isUnsigned() */ public boolean isUnsigned() { - return sds.isUnsigned(); + return ( qualifiers & IS_UNSIGNED) != 0; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBasicType#isShort() */ public boolean isShort() { - return sds.isShort(); + return ( qualifiers & IS_SHORT) != 0; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBasicType#isLong() */ public boolean isLong() { - return sds.isLong(); + return ( qualifiers & IS_LONG) != 0; } public boolean isLongLong() { - return sds.isLongLong(); + return ( qualifiers & IS_LONGLONG) != 0; } public boolean isSameType(IType obj) { @@ -103,7 +126,10 @@ public class CBasicType implements ICBasicType { * @see org.eclipse.cdt.core.dom.ast.IBasicType#getValue() */ public IASTExpression getValue() { - // TODO Auto-generated method stub - return null; + return value; + } + + public void setValue( IASTExpression expression ){ + this.value = expression; } } 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 2f9720c8e64..51b7b1f46c2 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 @@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; @@ -27,16 +26,28 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; */ public class CQualifierType implements ICQualifierType, ITypeContainer { - IASTDeclSpecifier declSpec = null; - IType type = null; + private boolean isConst; + private boolean isVolatile; + private boolean isRestrict; + private IType type = null; /** * CQualifierType has an IBasicType to keep track of the basic type information. * * @param type the CQualifierType's IBasicType */ - public CQualifierType(IASTDeclSpecifier declSpec) { - this.declSpec = declSpec; + public CQualifierType(ICASTDeclSpecifier declSpec) { + this.type = resolveType( declSpec ); + this.isConst = declSpec.isConst(); + this.isVolatile = declSpec.isVolatile(); + this.isRestrict = declSpec.isRestrict(); + } + + public CQualifierType( IType type, boolean isConst, boolean isVolatile, boolean isRestrict ){ + this.type = type; + this.isConst = isConst; + this.isVolatile = isVolatile; + this.isRestrict = isRestrict; } public boolean isSameType( IType obj ){ @@ -64,48 +75,47 @@ public class CQualifierType implements ICQualifierType, ITypeContainer { * @see org.eclipse.cdt.core.dom.ast.IQualifierType#isConst() */ public boolean isConst() { - if (declSpec == null) return false; - return declSpec.isConst(); + return isConst; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IQualifierType#isVolatile() */ public boolean isVolatile() { - if (declSpec == null) return false; - return declSpec.isVolatile(); + return isVolatile; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.c.ICQualifierType#isRestrict() */ public boolean isRestrict() { - if (declSpec == null) return false; - return (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict()); + return isRestrict; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IQualifierType#getType() */ - public IType getType() { - if (type == null) { - if( declSpec instanceof ICASTTypedefNameSpecifier ){ - ICASTTypedefNameSpecifier nameSpec = (ICASTTypedefNameSpecifier) declSpec; - type = (IType) nameSpec.getName().resolveBinding(); - } else if( declSpec instanceof IASTElaboratedTypeSpecifier ){ - IASTElaboratedTypeSpecifier elabTypeSpec = (IASTElaboratedTypeSpecifier) declSpec; - type = (IType) elabTypeSpec.getName().resolveBinding(); - } else if( declSpec instanceof IASTCompositeTypeSpecifier ){ - IASTCompositeTypeSpecifier compTypeSpec = (IASTCompositeTypeSpecifier) declSpec; - type = (IType) compTypeSpec.getName().resolveBinding(); - } else { - type = new CBasicType((ICASTSimpleDeclSpecifier)declSpec); - } + private IType resolveType( ICASTDeclSpecifier declSpec ) { + IType t = null; + if( declSpec instanceof ICASTTypedefNameSpecifier ){ + ICASTTypedefNameSpecifier nameSpec = (ICASTTypedefNameSpecifier) declSpec; + t = (IType) nameSpec.getName().resolveBinding(); + } else if( declSpec instanceof IASTElaboratedTypeSpecifier ){ + IASTElaboratedTypeSpecifier elabTypeSpec = (IASTElaboratedTypeSpecifier) declSpec; + t = (IType) elabTypeSpec.getName().resolveBinding(); + } else if( declSpec instanceof IASTCompositeTypeSpecifier ){ + IASTCompositeTypeSpecifier compTypeSpec = (IASTCompositeTypeSpecifier) declSpec; + t = (IType) compTypeSpec.getName().resolveBinding(); + } else { + t = new CBasicType((ICASTSimpleDeclSpecifier)declSpec); } - return type; + return t; } + public IType getType(){ + return type; + } public void setType( IType t ){ type = t; } 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 e49c42bc17b..a68fc3a27c4 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 @@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException; 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.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; @@ -26,6 +27,8 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTExpressionList; +import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; @@ -34,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -46,8 +50,10 @@ import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +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; @@ -77,7 +83,9 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; import org.eclipse.cdt.core.dom.ast.c.ICScope; +import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -425,7 +433,7 @@ public class CVisitor { protected static final ASTNodeProperty STRING_LOOKUP_PROPERTY = new ASTNodeProperty("CVisitor.STRING_LOOKUP_PROPERTY - STRING_LOOKUP"); //$NON-NLS-1$ protected static final ASTNodeProperty STRING_LOOKUP_TAGS_PROPERTY = new ASTNodeProperty("CVisitor.STRING_LOOKUP_TAGS_PROPERTY - STRING_LOOKUP"); //$NON-NLS-1$ - + private static final String SIZE_T = "size_t"; //$NON-NLS-1$ //lookup bits private static final int COMPLETE = 0; private static final int CURRENT_SCOPE = 1; @@ -609,7 +617,7 @@ public class CVisitor { return null; } - private static IType getExpressionType( IASTExpression expression ) { + public static IType getExpressionType( IASTExpression expression ) { try{ if( expression instanceof IASTIdExpression ){ IBinding binding = ((IASTIdExpression)expression).getName().resolveBinding(); @@ -639,7 +647,112 @@ public class CVisitor { return new CPointerType( type ); } return type; - } + } else if( expression instanceof IASTLiteralExpression ){ + switch( ((IASTLiteralExpression) expression).getKind() ){ + case IASTLiteralExpression.lk_char_constant: + return new CBasicType( IBasicType.t_char, 0, expression ); + case IASTLiteralExpression.lk_float_constant: + return new CBasicType( IBasicType.t_float, 0, expression ); + case IASTLiteralExpression.lk_integer_constant: + return new CBasicType( IBasicType.t_int, 0, expression ); + case IASTLiteralExpression.lk_string_literal: + IType type = new CBasicType( IBasicType.t_char, 0, expression ); + type = new CQualifierType( type, true, false, false ); + return new CPointerType( type ); + } + } else if( expression instanceof IASTBinaryExpression ){ + IASTBinaryExpression binary = (IASTBinaryExpression) expression; + int op = binary.getOperator(); + IType result = null; + switch( op ){ + case IASTBinaryExpression.op_lessEqual: + case IASTBinaryExpression.op_lessThan: + case IASTBinaryExpression.op_greaterEqual: + case IASTBinaryExpression.op_greaterThan: + case IASTBinaryExpression.op_logicalAnd: + case IASTBinaryExpression.op_logicalOr: + case IASTBinaryExpression.op_equals: + case IASTBinaryExpression.op_notequals: + result = new CBasicType( IBasicType.t_int, 0 ); + break; + case IASTBinaryExpression.op_plus: + case IASTBinaryExpression.op_minus: + IType t = getExpressionType( ((IASTBinaryExpression) expression).getOperand1() ); + if( t instanceof IPointerType ) + result = t; + else{ + result = getExpressionType( ((IASTBinaryExpression) expression).getOperand2() ); + } + break; + default: + result = getExpressionType( ((IASTBinaryExpression) expression).getOperand1() ); + } + + if( result instanceof CBasicType ){ + ((CBasicType)result).setValue( expression ); + } + return result; + } else if( expression instanceof IASTUnaryExpression ) { + int op = ((IASTUnaryExpression)expression).getOperator(); + if( op == IASTUnaryExpression.op_sizeof ){ + IScope scope = getContainingScope( expression ); + IBinding [] bs = scope.find( SIZE_T ); + if( bs.length > 0 && bs[0] instanceof IType ){ + return (IType) bs[0]; + } + return new CBasicType( IBasicType.t_int, CBasicType.IS_LONG | CBasicType.IS_UNSIGNED, expression ); + } + IType type = getExpressionType(((IASTUnaryExpression)expression).getOperand() ); + + if( op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType) ){ + try { + return ((ITypeContainer)type).getType(); + } catch (DOMException e) { + return e.getProblem(); + } + } else if( op == IASTUnaryExpression.op_amper ){ + return new CPointerType( type ); + } else if ( type instanceof CBasicType ){ + ((CBasicType)type).setValue( expression ); + } + return type; + } else if( expression instanceof IASTFieldReference ){ + IBinding binding = (IBinding) findBinding( (IASTFieldReference) expression, false ); + if( binding instanceof IVariable ) + return ((IVariable)binding).getType(); + else if( binding instanceof IFunction ) + return ((IFunction)binding).getType(); + else if( binding instanceof IEnumerator ) + return ((IEnumerator)binding).getType(); + } else if( expression instanceof IASTExpressionList ){ + IASTExpression [] exps = ((IASTExpressionList)expression).getExpressions(); + return getExpressionType( exps[ exps.length - 1 ] ); + } else if( expression instanceof IASTTypeIdExpression ){ + IASTTypeIdExpression typeidExp = (IASTTypeIdExpression) expression; + if( typeidExp.getOperator() == IASTTypeIdExpression.op_sizeof ){ + IScope scope = getContainingScope( typeidExp ); + IBinding [] bs = scope.find( SIZE_T ); + if( bs.length > 0 && bs[0] instanceof IType ){ + return (IType) bs[0]; + } + return new CBasicType( IBasicType.t_int, CBasicType.IS_LONG | CBasicType.IS_UNSIGNED ); + } + return createType( typeidExp.getTypeId().getAbstractDeclarator() ); + } else if( expression instanceof IASTArraySubscriptExpression ){ + IType t = getExpressionType( ((IASTArraySubscriptExpression) expression).getArrayExpression() ); + if( t instanceof IPointerType ) + return ((IPointerType)t).getType(); + else if( t instanceof IArrayType ) + return ((IArrayType)t).getType(); + } else if( expression instanceof IGNUASTCompoundStatementExpression ){ + IASTCompoundStatement compound = ((IGNUASTCompoundStatementExpression)expression).getCompoundStatement(); + IASTStatement [] statements = compound.getStatements(); + if( statements.length > 0 ){ + IASTStatement st = statements[ statements.length - 1 ]; + if( st instanceof IASTExpressionStatement ) + return getExpressionType( ((IASTExpressionStatement)st).getExpression() ); + } + } } catch( DOMException e ){ return e.getProblem(); } @@ -1443,7 +1556,7 @@ public class CVisitor { if( isParameter && node.getParent().getParent() instanceof IASTFunctionDefinition ){ type = createBaseType( declSpec ); } else { - type = createType( declSpec ); + type = createType( (ICASTDeclSpecifier) declSpec ); } type = createType( type, declarator ); @@ -1504,7 +1617,12 @@ public class CVisitor { * @return the base IType */ public static IType createBaseType( IASTDeclSpecifier declSpec ) { - if (declSpec instanceof ICASTSimpleDeclSpecifier) { + if( declSpec instanceof IGCCASTSimpleDeclSpecifier ){ + IASTExpression exp = ((IGCCASTSimpleDeclSpecifier)declSpec).getTypeofExpression(); + if( exp != null ) + return getExpressionType( exp ); + return new CBasicType( (ICASTSimpleDeclSpecifier) declSpec ); + } else if (declSpec instanceof ICASTSimpleDeclSpecifier) { return new CBasicType((ICASTSimpleDeclSpecifier)declSpec); } IBinding binding = null; @@ -1525,9 +1643,10 @@ public class CVisitor { return new ProblemBinding( name, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray() ); } - public static IType createType( IASTDeclSpecifier declSpec ) { - if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict())) + public static IType createType( ICASTDeclSpecifier declSpec ) { + if (declSpec.isConst() || declSpec.isVolatile() || declSpec.isRestrict()) { return new CQualifierType(declSpec); + } return createBaseType( declSpec ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCASTSimpleDeclSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCASTSimpleDeclSpecifier.java new file mode 100644 index 00000000000..70d2dea76b3 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCASTSimpleDeclSpecifier.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on May 18, 2005 + */ +package org.eclipse.cdt.internal.core.dom.parser.c; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier; + +/** + * @author aniefer + * + */ +public class GCCASTSimpleDeclSpecifier extends CASTSimpleDeclSpecifier + implements IGCCASTSimpleDeclSpecifier { + + private IASTExpression typeOfExpression; + + /** + * + */ + public GCCASTSimpleDeclSpecifier() { + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier#setTypeofExpression(org.eclipse.cdt.core.dom.ast.IASTExpression) + */ + public void setTypeofExpression(IASTExpression typeofExpression) { + this.typeOfExpression = typeofExpression; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier#getTypeofExpression() + */ + public IASTExpression getTypeofExpression() { + return typeOfExpression; + } + + public boolean accept( ASTVisitor action ){ + if( action.shouldVisitDeclSpecifiers ){ + switch( action.visit( this ) ){ + case ASTVisitor.PROCESS_ABORT : return false; + case ASTVisitor.PROCESS_SKIP : return true; + default : break; + } + } + if( typeOfExpression != null ) + if( !typeOfExpression.accept( action ) ) return false; + + return true; + } +} 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 abf6b8b90ad..4c75e3cd0dd 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 @@ -91,6 +91,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTArrayRangeDesignator; +import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier; import org.eclipse.cdt.core.parser.EndOfFileException; import org.eclipse.cdt.core.parser.IGCCToken; import org.eclipse.cdt.core.parser.IParserLogService; @@ -1551,7 +1552,18 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { name.setPropertyInParent(IASTNamedTypeSpecifier.NAME); return declSpec; } - ICASTSimpleDeclSpecifier declSpec = createSimpleTypeSpecifier(); + ICASTSimpleDeclSpecifier declSpec = null; + if (typeofExpression != null) { + declSpec = createGCCSimpleTypeSpecifier(); + ((IGCCASTSimpleDeclSpecifier) declSpec) + .setTypeofExpression(typeofExpression); + typeofExpression.setParent(declSpec); + typeofExpression + .setPropertyInParent(IGCCASTSimpleDeclSpecifier.TYPEOF_EXPRESSION); + } else { + declSpec = createSimpleTypeSpecifier(); + } + declSpec.setConst(isConst); declSpec.setRestrict(isRestrict); declSpec.setVolatile(isVolatile); @@ -1564,8 +1576,12 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { declSpec.setUnsigned(isUnsigned); declSpec.setSigned(isSigned); declSpec.setShort(isShort); - ((ASTNode) declSpec).setOffsetAndLength(startingOffset, - (last != null) ? last.getEndOffset() - startingOffset : 0); + if( typeofExpression != null && last == null ){ + ((ASTNode)declSpec).setOffsetAndLength( (ASTNode)typeofExpression ); + } else { + ((ASTNode) declSpec).setOffsetAndLength(startingOffset, + (last != null) ? last.getEndOffset() - startingOffset : 0); + } return declSpec; } @@ -1576,6 +1592,10 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { return new CASTSimpleDeclSpecifier(); } + protected IGCCASTSimpleDeclSpecifier createGCCSimpleTypeSpecifier() { + return new GCCASTSimpleDeclSpecifier(); + } + /** * @return */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 5344caa184c..2b9c393f265 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -1528,7 +1528,7 @@ public class CPPVisitor { int bits = ( spec.isLong() ? CPPBasicType.IS_LONG : 0 ) | ( spec.isShort() ? CPPBasicType.IS_SHORT : 0 ) | ( spec.isSigned() ? CPPBasicType.IS_SIGNED: 0 ) | - ( spec.isUnsigned() ? CPPBasicType.IS_SHORT : 0 ); + ( spec.isUnsigned() ? CPPBasicType.IS_UNSIGNED : 0 ); if( spec instanceof IGPPASTSimpleDeclSpecifier ){ IGPPASTSimpleDeclSpecifier gspec = (IGPPASTSimpleDeclSpecifier) spec; if( gspec.getTypeofExpression() != null ){ @@ -1732,8 +1732,20 @@ public class CPPVisitor { } else if( expression instanceof IASTUnaryExpression ) { + int op = ((IASTUnaryExpression)expression).getOperator(); + if( op == IASTTypeIdExpression.op_sizeof ){ + IScope scope = getContainingScope( expression ); + try { + IBinding [] bs = scope.find( SIZE_T ); + if( bs.length > 0 && bs[0] instanceof IType ){ + return (IType) bs[0]; + } + } catch (DOMException e) { + } + return new CPPBasicType( IBasicType.t_int, CPPBasicType.IS_LONG | CPPBasicType.IS_UNSIGNED ); + } + IType type = getExpressionType(((IASTUnaryExpression)expression).getOperand() ); - int op = ((IASTUnaryExpression)expression).getOperator(); if( op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType) ){ try { return ((ITypeContainer)type).getType(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 1efb0763354..8eff6cc302c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -3335,9 +3335,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } else simpleDeclSpec = createSimpleDeclSpecifier(); - int l = last != null ? last.getEndOffset() - firstToken.getOffset() : 0; - ((ASTNode) simpleDeclSpec) - .setOffsetAndLength(firstToken.getOffset(), l); + if( last == null && typeofExpression != null ){ + ((ASTNode) simpleDeclSpec).setOffsetAndLength((ASTNode) typeofExpression); + } else { + int l = last != null ? last.getEndOffset() - firstToken.getOffset() : 0; + ((ASTNode) simpleDeclSpec) + .setOffsetAndLength(firstToken.getOffset(), l); + } simpleDeclSpec.setConst(isConst); simpleDeclSpec.setVolatile(isVolatile); if (simpleDeclSpec instanceof IGPPASTDeclSpecifier)