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)