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[0]).taken());
assertFalse(((IASTPreprocessorIfdefStatement) stmts[1]).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() { public IType getExpressionType() {
if (getOperator() == op_sizeof) { if (getOperator() == op_sizeof) {
return CVisitor.getSize_T(this); return CVisitor.get_SIZE_T(this);
} }
return CVisitor.createType(typeId.getAbstractDeclarator()); return CVisitor.createType(typeId.getAbstractDeclarator());
} }

View file

@ -107,9 +107,12 @@ public class CASTUnaryExpression extends ASTNode implements IASTUnaryExpression,
} }
public IType getExpressionType() { public IType getExpressionType() {
int op = getOperator();
if (op == op_sizeof) {
return CVisitor.get_SIZE_T(this);
}
final IType exprType = getOperand().getExpressionType(); final IType exprType = getOperand().getExpressionType();
IType type = CVisitor.unwrapTypedefs(exprType); IType type = CVisitor.unwrapTypedefs(exprType);
int op = getOperator();
switch(op) { switch(op) {
case op_star: case op_star:
if (type instanceof IPointerType || type instanceof IArrayType) { 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. * Collection of methods to find information in an AST.
*/ */
public class CVisitor extends ASTQueries { 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 { public static class CollectProblemsAction extends ASTVisitor {
{ {
shouldVisitDeclarations = true; shouldVisitDeclarations = true;
@ -647,9 +652,10 @@ public class CVisitor extends ASTQueries {
return new CBasicType(Kind.eInt, 0, expr); return new CBasicType(Kind.eInt, 0, expr);
} }
static IType getSize_T(IASTExpression expr) { static IType get_SIZE_T(IASTExpression expr) {
IScope scope = getContainingScope(expr); IASTTranslationUnit tu= expr.getTranslationUnit();
IBinding[] bs = scope.find(SIZE_T); if (tu != null) {
IBinding[] bs = tu.getScope().find(SIZE_T);
for (IBinding b : bs) { for (IBinding b : bs) {
if (b instanceof IType) { if (b instanceof IType) {
if (!(b instanceof ICInternalBinding) || if (!(b instanceof ICInternalBinding) ||
@ -658,7 +664,8 @@ public class CVisitor extends ASTQueries {
} }
} }
} }
return new CBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED); }
return UNSIGNED_LONG_INT;
} }
static IType unwrapTypedefs(IType type) { 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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.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.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; 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. * Collection of methods to extract information from a C++ translation unit.
*/ */
public class CPPVisitor extends ASTQueries { public class CPPVisitor extends ASTQueries {
public static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$ private static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
public static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$ private static final CPPBasicType INT_TYPE = new CPPBasicType(Kind.eInt, 0);
static final char[] BEGIN = "begin".toCharArray(); //$NON-NLS-1$ static final char[] BEGIN = "begin".toCharArray(); //$NON-NLS-1$
public static final String STD = "std"; //$NON-NLS-1$ static final String STD = "std"; //$NON-NLS-1$
public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$ private static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$
private static final String INITIALIZER_LIST = "initializer_list"; //$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. // Thread-local set of DeclSpecifiers for which auto types are being created.
// Used to prevent infinite recursion while processing invalid self-referencing // Used to prevent infinite recursion while processing invalid self-referencing
@ -2091,57 +2095,42 @@ public class CPPVisitor extends ASTQueries {
} }
public static IType getPointerDiffType(final IASTBinaryExpression binary) { public static IType getPointerDiffType(final IASTBinaryExpression binary) {
CPPBasicType basicType; IType t= getStdType(binary, PTRDIFF_T);
IScope scope = getContainingScope(binary); return t != null ? t : INT_TYPE;
IBinding[] bs= CPPSemantics.findBindings(scope, PTRDIFF_T, false, binary); }
private static IType getStdType(final IASTNode node, char[] name) {
IBinding[] std= node.getTranslationUnit().getScope().find(STD);
for (IBinding binding : std) {
if (binding instanceof ICPPNamespace) {
final ICPPNamespaceScope scope = ((ICPPNamespace) binding).getNamespaceScope();
IBinding[] bs= CPPSemantics.findBindings(scope, name, false, node);
if (bs.length > 0) { if (bs.length > 0) {
for (IBinding b : bs) { for (IBinding b : bs) {
if (b instanceof IType && CPPSemantics.declaredBefore(b, binary, false)) { if (b instanceof IType && CPPSemantics.declaredBefore(b, node, false)) {
return (IType) b; return (IType) b;
} }
} }
} }
basicType= new CPPBasicType(Kind.eInt, 0); }
basicType.setFromExpression(binary); }
return basicType; return null;
} }
public static IType get_type_info(IASTExpression expression) { public static IType get_type_info(IASTExpression expression) {
IBinding[] std= expression.getTranslationUnit().getScope().find(STD); IType t= getStdType(expression, TYPE_INFO);
for (IBinding binding : std) { return t != null ? t : INT_TYPE;
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) { public static IType get_SIZE_T(IASTNode sizeofExpr) {
IScope scope = getContainingScope(sizeofExpr); IType t= getStdType(sizeofExpr, SIZE_T);
IBinding[] bs = CPPSemantics.findBindings(scope, SIZE_T, false, sizeofExpr); return t != null ? t : UNSIGNED_LONG;
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) { public static ICPPClassTemplate get_initializer_list(IASTNode node) {
IBinding[] std= node.getTranslationUnit().getScope().find(STD); IType t= getStdType(node, INITIALIZER_LIST);
for (IBinding binding : std) { if (t instanceof ICPPClassTemplate)
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; return (ICPPClassTemplate) t;
}
}
}
}
return null; return null;
} }