diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index 9966c5c8390..c6392ba67ef 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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())); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java index f732e93a0e1..c816c14fd93 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java @@ -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()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java index 7ddb5d5447d..ab1fe112d4a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index b2ee9350d7f..56598d75ef4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index ebf43313861..e720e48d894 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -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);