diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 88e30cce75c..b072be735fc 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -5911,4 +5911,14 @@ public class AST2CPPTests extends AST2BaseTest { BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); ba.assertNonProblem("foo();/**/", 3); } + + // namespace std {class type_info{public: const char* name() const;};} + // int main() { + // int s; + // typeid(int).name(); + // typeid(s).name(); + // } + public void testTypeid_Bug209578() throws Exception { + parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 928bbc07e6d..0c109eecc83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -2026,7 +2026,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { IASTExpression expr2= expression(); endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset(); - expr= buildTypeIdExpression(IASTTypeIdExpression.op_typeid, typeid, typeidOffset, calculateEndOffset(typeid)); + expr= buildTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid, typeidOffset, calculateEndOffset(typeid)); IASTExpressionList expressionList = createExpressionList(); ((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 3bd0bc62998..59c188468f8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -1186,8 +1186,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break; case IToken.t_typeid: int so = consume().getOffset(); - return parseTypeidInParenthesisOrUnaryExpression(true, so, ICPPASTTypeIdExpression.op_typeid, ICPPASTUnaryExpression.op_typeid); - + firstExpression= parseTypeidInParenthesisOrUnaryExpression(true, so, ICPPASTTypeIdExpression.op_typeid, ICPPASTUnaryExpression.op_typeid); + break; + default: firstExpression = primaryExpression(); break; 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 4aa32ecfd74..0938bb8e680 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 @@ -194,6 +194,8 @@ import org.eclipse.cdt.internal.core.index.IIndexScope; public class CPPVisitor { public static final String SIZE_T = "size_t"; //$NON-NLS-1$ public static final String PTRDIFF_T = "ptrdiff_t"; //$NON-NLS-1$ + public static final String STD = "std"; //$NON-NLS-1$ + public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$ /** * @param name @@ -1947,17 +1949,12 @@ public class CPPVisitor { } return getExpressionType(((IASTBinaryExpression) expression).getOperand1()); } else if (expression instanceof IASTUnaryExpression) { - int op = ((IASTUnaryExpression)expression).getOperator(); - if (op == IASTUnaryExpression.op_sizeof) { - IScope scope = getContainingScope(expression); - try { - IBinding[] bs = scope.find(SIZE_T); - if (bs.length > 0 && bs[0] instanceof IType) { - return (IType) bs[0]; - } - } catch (DOMException e) { - } - return new CPPBasicType(IBasicType.t_int, ICPPBasicType.IS_LONG | ICPPBasicType.IS_UNSIGNED); + final int op= ((IASTUnaryExpression)expression).getOperator(); + switch (op) { + case IASTUnaryExpression.op_sizeof: + return get_SIZE_T(expression); + case IASTUnaryExpression.op_typeid: + return get_type_info(expression); } IType type = getExpressionType(((IASTUnaryExpression)expression).getOperand()); @@ -2031,17 +2028,12 @@ public class CPPVisitor { return getExpressionType(exps[exps.length - 1]); } else if (expression instanceof ICPPASTTypeIdExpression) { ICPPASTTypeIdExpression typeidExp = (ICPPASTTypeIdExpression) expression; - if (typeidExp.getOperator() == IASTTypeIdExpression.op_sizeof) { - IScope scope = getContainingScope(typeidExp); - try { - IBinding[] bs = scope.find(SIZE_T); - if (bs.length > 0 && bs[0] instanceof IType) { - return (IType) bs[0]; - } - } catch (DOMException e) { - } - return new CPPBasicType(IBasicType.t_int, ICPPBasicType.IS_LONG | ICPPBasicType.IS_UNSIGNED); - } + switch (typeidExp.getOperator()) { + case IASTTypeIdExpression.op_sizeof: + return get_SIZE_T(typeidExp); + case IASTTypeIdExpression.op_typeid: + return get_type_info(expression); + } return createType(typeidExp.getTypeId()); } else if (expression instanceof IASTArraySubscriptExpression) { IType t = getExpressionType(((IASTArraySubscriptExpression) expression).getArrayExpression()); @@ -2094,6 +2086,36 @@ public class CPPVisitor { } return null; } + + private static IType get_type_info(IASTExpression expression) { + try { + 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; + } + } + } + } + } catch (DOMException e) { + } + return new CPPBasicType(IBasicType.t_int, 0); + } + + private static IType get_SIZE_T(IASTNode sizeofExpr) { + IScope scope = getContainingScope(sizeofExpr); + try { + IBinding[] bs = scope.find(SIZE_T); + if (bs.length > 0 && bs[0] instanceof IType) { + return (IType) bs[0]; + } + } catch (DOMException e) { + } + return new CPPBasicType(IBasicType.t_int, ICPPBasicType.IS_LONG | ICPPBasicType.IS_UNSIGNED); + } private static IType classifyTypeOfFloatLiteral(final IASTLiteralExpression expr) { final String lit= expr.toString();