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:
parent
5eb921be84
commit
0e70cab178
5 changed files with 81 additions and 59 deletions
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue