1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 355052: Type of sizeof expression.

This commit is contained in:
Markus Schorn 2011-09-06 15:52:37 +02:00
parent 5eb921be84
commit 0e70cab178
5 changed files with 81 additions and 59 deletions

View file

@ -7337,4 +7337,27 @@ public class AST2Tests extends AST2BaseTest {
assertFalse(((IASTPreprocessorIfdefStatement) stmts[0]).taken());
assertFalse(((IASTPreprocessorIfdefStatement) stmts[1]).taken());
}
// void a() {
// typedef float size_t;
// sizeof(10); // wrong - getExpressionType returns float
// sizeof(int); // wrong - getExpressionType returns float
// }
public void testTypeOfSizeof_Bug355052() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP);
IASTFunctionDefinition a= getDeclaration(tu, 0);
IASTExpressionStatement es= getStatement(a, 1);
assertEquals("unsigned long int", ASTTypeUtil.getType(es.getExpression().getExpressionType()));
es= getStatement(a, 2);
assertEquals("unsigned long int", ASTTypeUtil.getType(es.getExpression().getExpressionType()));
tu= parseAndCheckBindings(code, ParserLanguage.C);
a= getDeclaration(tu, 0);
es= getStatement(a, 1);
assertEquals("unsigned long int", ASTTypeUtil.getType(es.getExpression().getExpressionType()));
es= getStatement(a, 2);
assertEquals("unsigned long int", ASTTypeUtil.getType(es.getExpression().getExpressionType()));
}
}

View file

@ -94,7 +94,7 @@ public class CASTTypeIdExpression extends ASTNode implements IASTTypeIdExpressio
public IType getExpressionType() {
if (getOperator() == op_sizeof) {
return CVisitor.getSize_T(this);
return CVisitor.get_SIZE_T(this);
}
return CVisitor.createType(typeId.getAbstractDeclarator());
}

View file

@ -107,9 +107,12 @@ public class CASTUnaryExpression extends ASTNode implements IASTUnaryExpression,
}
public IType getExpressionType() {
int op = getOperator();
if (op == op_sizeof) {
return CVisitor.get_SIZE_T(this);
}
final IType exprType = getOperand().getExpressionType();
IType type = CVisitor.unwrapTypedefs(exprType);
int op = getOperator();
switch(op) {
case op_star:
if (type instanceof IPointerType || type instanceof IArrayType) {

View file

@ -104,6 +104,11 @@ import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
* Collection of methods to find information in an AST.
*/
public class CVisitor extends ASTQueries {
/**
*
*/
private static final CBasicType UNSIGNED_LONG_INT = new CBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
public static class CollectProblemsAction extends ASTVisitor {
{
shouldVisitDeclarations = true;
@ -646,19 +651,21 @@ public class CVisitor extends ASTQueries {
return new CBasicType(Kind.eInt, 0, expr);
}
static IType getSize_T(IASTExpression expr) {
IScope scope = getContainingScope(expr);
IBinding[] bs = scope.find(SIZE_T);
for (IBinding b : bs) {
if (b instanceof IType) {
if (!(b instanceof ICInternalBinding) ||
CVisitor.declaredBefore(((ICInternalBinding) b).getPhysicalNode(), expr)) {
return (IType) b;
static IType get_SIZE_T(IASTExpression expr) {
IASTTranslationUnit tu= expr.getTranslationUnit();
if (tu != null) {
IBinding[] bs = tu.getScope().find(SIZE_T);
for (IBinding b : bs) {
if (b instanceof IType) {
if (!(b instanceof ICInternalBinding) ||
CVisitor.declaredBefore(((ICInternalBinding) b).getPhysicalNode(), expr)) {
return (IType) b;
}
}
}
}
return new CBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
return UNSIGNED_LONG_INT;
}
static IType unwrapTypedefs(IType type) {

View file

@ -137,6 +137,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
@ -195,12 +196,15 @@ import org.eclipse.cdt.internal.core.index.IIndexScope;
* Collection of methods to extract information from a C++ translation unit.
*/
public class CPPVisitor extends ASTQueries {
public static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$
public static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$
private static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
private static final CPPBasicType INT_TYPE = new CPPBasicType(Kind.eInt, 0);
static final char[] BEGIN = "begin".toCharArray(); //$NON-NLS-1$
public static final String STD = "std"; //$NON-NLS-1$
public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$
private static final String INITIALIZER_LIST = "initializer_list"; //$NON-NLS-1$
static final String STD = "std"; //$NON-NLS-1$
private static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$
private static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$
private static final char[] TYPE_INFO= "type_info".toCharArray(); //$NON-NLS-1$
private static final char[] INITIALIZER_LIST = "initializer_list".toCharArray(); //$NON-NLS-1$
// Thread-local set of DeclSpecifiers for which auto types are being created.
// Used to prevent infinite recursion while processing invalid self-referencing
@ -2091,53 +2095,21 @@ public class CPPVisitor extends ASTQueries {
}
public static IType getPointerDiffType(final IASTBinaryExpression binary) {
CPPBasicType basicType;
IScope scope = getContainingScope(binary);
IBinding[] bs= CPPSemantics.findBindings(scope, PTRDIFF_T, false, binary);
if (bs.length > 0) {
for (IBinding b : bs) {
if (b instanceof IType && CPPSemantics.declaredBefore(b, binary, false)) {
return (IType) b;
}
}
}
basicType= new CPPBasicType(Kind.eInt, 0);
basicType.setFromExpression(binary);
return basicType;
IType t= getStdType(binary, PTRDIFF_T);
return t != null ? t : INT_TYPE;
}
public static IType get_type_info(IASTExpression expression) {
IBinding[] std= expression.getTranslationUnit().getScope().find(STD);
for (IBinding binding : std) {
if (binding instanceof ICPPNamespace) {
IBinding[] typeInfo= ((ICPPNamespace) binding).getNamespaceScope().find(TYPE_INFO);
for (IBinding t : typeInfo) {
if (t instanceof ICPPClassType) {
return (ICPPClassType) t;
}
}
}
}
return new CPPBasicType(Kind.eInt, 0);
}
public static IType get_SIZE_T(IASTNode sizeofExpr) {
IScope scope = getContainingScope(sizeofExpr);
IBinding[] bs = CPPSemantics.findBindings(scope, SIZE_T, false, sizeofExpr);
if (bs.length > 0 && bs[0] instanceof IType) {
return (IType) bs[0];
}
return new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
}
public static ICPPClassTemplate get_initializer_list(IASTNode node) {
private static IType getStdType(final IASTNode node, char[] name) {
IBinding[] std= node.getTranslationUnit().getScope().find(STD);
for (IBinding binding : std) {
if (binding instanceof ICPPNamespace) {
IBinding[] initializer_list= ((ICPPNamespace) binding).getNamespaceScope().find(INITIALIZER_LIST);
for (IBinding t : initializer_list) {
if (t instanceof ICPPClassTemplate) {
return (ICPPClassTemplate) t;
final ICPPNamespaceScope scope = ((ICPPNamespace) binding).getNamespaceScope();
IBinding[] bs= CPPSemantics.findBindings(scope, name, false, node);
if (bs.length > 0) {
for (IBinding b : bs) {
if (b instanceof IType && CPPSemantics.declaredBefore(b, node, false)) {
return (IType) b;
}
}
}
}
@ -2145,6 +2117,23 @@ public class CPPVisitor extends ASTQueries {
return null;
}
public static IType get_type_info(IASTExpression expression) {
IType t= getStdType(expression, TYPE_INFO);
return t != null ? t : INT_TYPE;
}
public static IType get_SIZE_T(IASTNode sizeofExpr) {
IType t= getStdType(sizeofExpr, SIZE_T);
return t != null ? t : UNSIGNED_LONG;
}
public static ICPPClassTemplate get_initializer_list(IASTNode node) {
IType t= getStdType(node, INITIALIZER_LIST);
if (t instanceof ICPPClassTemplate)
return (ICPPClassTemplate) t;
return null;
}
public static IASTProblem[] getProblems(IASTTranslationUnit tu) {
CollectProblemsAction action = new CollectProblemsAction();
tu.accept(action);