mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
- types of expressions in C bug 95858
- typeof( exp ) as declspecifier in C bug 93980
This commit is contained in:
parent
beeb963403
commit
c885f752da
9 changed files with 365 additions and 51 deletions
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
||||
/**
|
||||
* <code>t_typeof</code> represents a typeof() expression type.
|
||||
*/
|
||||
public static final int t_typeof = ICASTSimpleDeclSpecifier.t_last + 1;
|
||||
|
||||
/**
|
||||
* <code>t_last</code> is specified for subinterfaces.
|
||||
*/
|
||||
public static final int t_last = t_typeof;
|
||||
|
||||
/**
|
||||
* <code>TYPEOF_EXPRESSION</code> 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
|
||||
* <code>IASTExpression</code>
|
||||
*/
|
||||
public void setTypeofExpression(IASTExpression typeofExpression);
|
||||
|
||||
/**
|
||||
* Get the typeof expression.
|
||||
*
|
||||
* @return <code>IASTExpression</code>
|
||||
*/
|
||||
public IASTExpression getTypeofExpression();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue