diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 19350ee7d27..59c74e79b3e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -7004,4 +7004,35 @@ public class AST2TemplateTests extends AST2BaseTest { public void testDependentExpressions_395243d() throws Exception { parseAndCheckBindings(); } + + // template struct A {}; + // + // template + // struct A { + // static void m(); + // }; + // + // template + // struct B { + // enum { value = 1 }; + // }; + // + // template + // struct C { + // enum { id = B::value ? 0 : -1 }; + // }; + // + // template + // struct D { + // typedef A::id> E; + // }; + // + // void test() { + // D::E::m(); + // } + public void testDependentEnum_398696() throws Exception { + BindingAssertionHelper ah = getAssertionHelper(); + ah.assertNonProblem("D::E::m()", "m"); +// parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java index de5891334db..ff3726895e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2013 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; @@ -33,11 +34,11 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I setName(name); setValue(value); } - - protected void copyAbstractEnumerator(ASTEnumerator copy, CopyStyle style) { + + protected T copy(T copy, CopyStyle style) { copy.setName(name == null ? null : name.copy(style)); copy.setValue(value == null ? null : value.copy(style)); - copy.setOffsetAndLength(this); + return super.copy(copy, style); } @Override @@ -125,23 +126,26 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I } private void createEnumValues(IASTEnumerationSpecifier parent) { + IValue previousExplicitValue = null; + int delta = 0; IASTEnumerator[] etors= parent.getEnumerators(); - long cv= -1; - boolean isKnown= true; for (IASTEnumerator etor : etors) { - cv++; + IValue val; IASTExpression expr= etor.getValue(); if (expr != null) { - IValue val= Value.create(expr, Value.MAX_RECURSION_DEPTH); - Long nv= val.numericalValue(); - isKnown= false; - if (nv != null) { - isKnown= true; - cv= nv.longValue(); + val= Value.create(expr, Value.MAX_RECURSION_DEPTH); + previousExplicitValue = val; + delta = 1; + } else { + if (previousExplicitValue != null) { + val = Value.incrementedValue(previousExplicitValue, delta); + } else { + val = Value.create(delta); } + delta++; } if (etor instanceof ASTEnumerator) { - ((ASTEnumerator) etor).integralValue= isKnown ? Value.create(cv) : Value.UNKNOWN; + ((ASTEnumerator) etor).integralValue= val; } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java index 4e5a941bc05..8c074ef9932 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java @@ -39,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; @@ -53,16 +54,20 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; @@ -77,6 +82,7 @@ public class Value implements IValue { public static final int MAX_RECURSION_DEPTH = 25; public static final Value UNKNOWN= new Value("".toCharArray(), null); //$NON-NLS-1$ public static final Value NOT_INITIALIZED= new Value("<__>".toCharArray(), null); //$NON-NLS-1$ + private static final IType INT_TYPE= new CPPBasicType(ICPPBasicType.Kind.eInt, 0); private static final Number VALUE_CANNOT_BE_DETERMINED = new Number() { @Override @@ -271,6 +277,16 @@ public class Value implements IValue { return UNKNOWN; } + public static IValue incrementedValue(IValue value, int increment) { + Long val = value.numericalValue(); + if (val != null) { + return create(val.longValue() + increment); + } + ICPPEvaluation arg1 = value.getEvaluation(); + EvalFixed arg2 = new EvalFixed(INT_TYPE, ValueCategory.PRVALUE, create(increment)); + return create(new EvalBinary(IASTBinaryExpression.op_plus, arg1, arg2)); + } + private static Number applyUnaryTypeIdOperator(int operator, IType type, IASTNode point) { switch (operator) { case op_sizeof: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerator.java index b5706d94dac..1b596216df0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerator.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2005, 2011 IBM Corporation and others. + * Copyright (c) 2005, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * John Camelon (IBM Rational Software) - Initial API and implementation + * John Camelon (IBM Rational Software) - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; @@ -34,11 +34,6 @@ public class CASTEnumerator extends ASTEnumerator { @Override public CASTEnumerator copy(CopyStyle style) { - CASTEnumerator copy = new CASTEnumerator(); - copyAbstractEnumerator(copy, style); - if (style == CopyStyle.withLocations) { - copy.setCopyLocation(this); - } - return copy; + return copy(new CASTEnumerator(), style); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerator.java index fdd9fef35d6..0eee0c53ec3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerator.java @@ -1,13 +1,13 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * John Camelon (IBM) - Initial API and implementation - * Markus Schorn (Wind River Systems) + * John Camelon (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -35,11 +35,6 @@ public class CPPASTEnumerator extends ASTEnumerator { @Override public CPPASTEnumerator copy(CopyStyle style) { - CPPASTEnumerator copy = new CPPASTEnumerator(); - copyAbstractEnumerator(copy, style); - if (style == CopyStyle.withLocations) { - copy.setCopyLocation(this); - } - return copy; + return copy(new CPPASTEnumerator(), style); } }