1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 398696 - Name resolution problem with a conditional enum value.

This commit is contained in:
Sergey Prigogin 2013-01-21 19:33:31 -08:00
parent 424d913ba9
commit 9a0842acd5
5 changed files with 72 additions and 31 deletions

View file

@ -7004,4 +7004,35 @@ public class AST2TemplateTests extends AST2BaseTest {
public void testDependentExpressions_395243d() throws Exception { public void testDependentExpressions_395243d() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template<typename T, unsigned n> struct A {};
//
// template<typename T>
// struct A<T, 0> {
// static void m();
// };
//
// template <typename T>
// struct B {
// enum { value = 1 };
// };
//
// template <typename T>
// struct C {
// enum { id = B<T>::value ? 0 : -1 };
// };
//
// template<typename T>
// struct D {
// typedef A<T, C<T>::id> E;
// };
//
// void test() {
// D<bool>::E::m();
// }
public void testDependentEnum_398696() throws Exception {
BindingAssertionHelper ah = getAssertionHelper();
ah.assertNonProblem("D<bool>::E::m()", "m");
// parseAndCheckBindings();
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
@ -33,11 +34,11 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
setName(name); setName(name);
setValue(value); setValue(value);
} }
protected void copyAbstractEnumerator(ASTEnumerator copy, CopyStyle style) { protected <T extends ASTEnumerator> T copy(T copy, CopyStyle style) {
copy.setName(name == null ? null : name.copy(style)); copy.setName(name == null ? null : name.copy(style));
copy.setValue(value == null ? null : value.copy(style)); copy.setValue(value == null ? null : value.copy(style));
copy.setOffsetAndLength(this); return super.copy(copy, style);
} }
@Override @Override
@ -125,23 +126,26 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
} }
private void createEnumValues(IASTEnumerationSpecifier parent) { private void createEnumValues(IASTEnumerationSpecifier parent) {
IValue previousExplicitValue = null;
int delta = 0;
IASTEnumerator[] etors= parent.getEnumerators(); IASTEnumerator[] etors= parent.getEnumerators();
long cv= -1;
boolean isKnown= true;
for (IASTEnumerator etor : etors) { for (IASTEnumerator etor : etors) {
cv++; IValue val;
IASTExpression expr= etor.getValue(); IASTExpression expr= etor.getValue();
if (expr != null) { if (expr != null) {
IValue val= Value.create(expr, Value.MAX_RECURSION_DEPTH); val= Value.create(expr, Value.MAX_RECURSION_DEPTH);
Long nv= val.numericalValue(); previousExplicitValue = val;
isKnown= false; delta = 1;
if (nv != null) { } else {
isKnown= true; if (previousExplicitValue != null) {
cv= nv.longValue(); val = Value.incrementedValue(previousExplicitValue, delta);
} else {
val = Value.create(delta);
} }
delta++;
} }
if (etor instanceof ASTEnumerator) { if (etor instanceof ASTEnumerator) {
((ASTEnumerator) etor).integralValue= isKnown ? Value.create(cv) : Value.UNKNOWN; ((ASTEnumerator) etor).integralValue= val;
} }
} }
} }

View file

@ -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.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; 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.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; 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.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable; 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.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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; 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.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.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; 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.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; 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.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.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.dom.parser.cpp.semantics.TypeTraits;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; 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 int MAX_RECURSION_DEPTH = 25;
public static final Value UNKNOWN= new Value("<unknown>".toCharArray(), null); //$NON-NLS-1$ public static final Value UNKNOWN= new Value("<unknown>".toCharArray(), null); //$NON-NLS-1$
public static final Value NOT_INITIALIZED= 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() { private static final Number VALUE_CANNOT_BE_DETERMINED = new Number() {
@Override @Override
@ -271,6 +277,16 @@ public class Value implements IValue {
return UNKNOWN; 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) { private static Number applyUnaryTypeIdOperator(int operator, IType type, IASTNode point) {
switch (operator) { switch (operator) {
case op_sizeof: case op_sizeof:

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * 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; package org.eclipse.cdt.internal.core.dom.parser.c;
@ -34,11 +34,6 @@ public class CASTEnumerator extends ASTEnumerator {
@Override @Override
public CASTEnumerator copy(CopyStyle style) { public CASTEnumerator copy(CopyStyle style) {
CASTEnumerator copy = new CASTEnumerator(); return copy(new CASTEnumerator(), style);
copyAbstractEnumerator(copy, style);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
} }
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* John Camelon (IBM) - Initial API and implementation * John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -35,11 +35,6 @@ public class CPPASTEnumerator extends ASTEnumerator {
@Override @Override
public CPPASTEnumerator copy(CopyStyle style) { public CPPASTEnumerator copy(CopyStyle style) {
CPPASTEnumerator copy = new CPPASTEnumerator(); return copy(new CPPASTEnumerator(), style);
copyAbstractEnumerator(copy, style);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
} }
} }