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[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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue