1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-10 09:45:39 +02:00

Support aggregate initialization in EvalTypeId

The patch also improves the propagation of the point of instantiation
in CompositeValue.

Change-Id: I01d508ab901efeb18a5e6fdb144853b70e1fc829
This commit is contained in:
Nathan Ridge 2016-11-26 03:25:52 -05:00
parent c389f49659
commit d48ebf5d25
5 changed files with 23 additions and 17 deletions

View file

@ -9796,10 +9796,6 @@ public class AST2TemplateTests extends AST2TestBase {
public void testBraceInitialization_490475b() throws Exception { public void testBraceInitialization_490475b() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
IVariable waldo = helper.assertNonProblem("waldo"); IVariable waldo = helper.assertNonProblem("waldo");
// TODO(nathanridge): helper.assertVariableValue("waldo", -13);
// Actually test that we get the correct value.
// For this, we need to add support for aggregate initialization in EvalTypeId.
// For now, just test that attempting to evaluate doesn't throw an exception.
waldo.getInitialValue();
} }
} }

View file

@ -23,6 +23,9 @@ public class ConstructorTests extends TestBase {
public static TestSuite suite() {return suite(SingleProject.class);} public static TestSuite suite() {return suite(SingleProject.class);}
} }
public ConstructorTests() {setStrategy(new NonIndexingTestStrategy()); }
public static TestSuite suite() {return suite(NonIndexing.class);}
// struct S { // struct S {
// int x; // int x;
// constexpr S(int i) : x{i*i} {} // constexpr S(int i) : x{i*i} {}

View file

@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.dom.parser;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
@ -106,7 +107,7 @@ public final class CompositeValue implements IValue {
* Creates a value representing an instance of the given array type initialized with * Creates a value representing an instance of the given array type initialized with
* the elements of the given initializer list. * the elements of the given initializer list.
*/ */
public static IValue create(EvalInitList initList, IArrayType type) { public static IValue create(EvalInitList initList, IArrayType type, IASTNode point) {
Number arraySize = type.getSize().numberValue(); Number arraySize = type.getSize().numberValue();
if (arraySize == null) { if (arraySize == null) {
// Array size is dependent. TODO: Handle this? // Array size is dependent. TODO: Handle this?
@ -116,8 +117,8 @@ public final class CompositeValue implements IValue {
ICPPEvaluation[] values = new ICPPEvaluation[arraySize.intValue()]; ICPPEvaluation[] values = new ICPPEvaluation[arraySize.intValue()];
for (int i = 0; i < initList.getClauses().length; i++) { for (int i = 0; i < initList.getClauses().length; i++) {
ICPPEvaluation eval = initList.getClauses()[i]; ICPPEvaluation eval = initList.getClauses()[i];
IValue value = getValue(elementType, eval); IValue value = getValue(elementType, eval, point);
values[i] = new EvalFixed(elementType, eval.getValueCategory(null), value); values[i] = new EvalFixed(elementType, eval.getValueCategory(point), value);
} }
return new CompositeValue(initList, values); return new CompositeValue(initList, values);
} }
@ -125,12 +126,12 @@ public final class CompositeValue implements IValue {
/** /**
* Gets the value of an evaluation, interpreted as a value of the given type. * Gets the value of an evaluation, interpreted as a value of the given type.
*/ */
private static IValue getValue(IType type, ICPPEvaluation eval) { private static IValue getValue(IType type, ICPPEvaluation eval, IASTNode point) {
IValue value; IValue value;
if (type instanceof IArrayType && eval instanceof EvalInitList) { if (type instanceof IArrayType && eval instanceof EvalInitList) {
value = CompositeValue.create((EvalInitList) eval, (IArrayType) type); value = CompositeValue.create((EvalInitList) eval, (IArrayType) type, point);
} else if (type instanceof ICompositeType && eval instanceof EvalInitList) { } else if (type instanceof ICompositeType && eval instanceof EvalInitList) {
value = CompositeValue.create((EvalInitList) eval, (ICompositeType) type); value = CompositeValue.create((EvalInitList) eval, (ICompositeType) type, point);
} else if (eval instanceof EvalInitList) { } else if (eval instanceof EvalInitList) {
value = IntegralValue.UNKNOWN; value = IntegralValue.UNKNOWN;
} else { } else {
@ -143,15 +144,20 @@ public final class CompositeValue implements IValue {
* Creates a value representing an instance of the given composite type initialized with * Creates a value representing an instance of the given composite type initialized with
* the elements of the given initializer list. * the elements of the given initializer list.
*/ */
public static IValue create(EvalInitList initList, ICompositeType type) { public static IValue create(EvalInitList initList, ICompositeType type, IASTNode point) {
IField[] fields = type.getFields(); IField[] fields;
if (type instanceof ICPPClassType) {
fields = ClassTypeHelper.getFields((ICPPClassType) type, point);
} else {
fields = type.getFields();
}
ICPPEvaluation[] values = new ICPPEvaluation[fields.length]; ICPPEvaluation[] values = new ICPPEvaluation[fields.length];
ICPPEvaluation[] clauses = initList.getClauses(); ICPPEvaluation[] clauses = initList.getClauses();
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {
IField field = fields[i]; IField field = fields[i];
ICPPEvaluation eval = clauses[i]; ICPPEvaluation eval = clauses[i];
IType fieldType = field.getType(); IType fieldType = field.getType();
IValue value = getValue(fieldType, eval); IValue value = getValue(fieldType, eval, point);
values[i] = new EvalFixed(fieldType, eval.getValueCategory(null), value); values[i] = new EvalFixed(fieldType, eval.getValueCategory(null), value);
} }
return new CompositeValue(initList, values); return new CompositeValue(initList, values);

View file

@ -153,8 +153,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
if (EvalUtil.isCompilerGeneratedCtor(ctor)) { if (EvalUtil.isCompilerGeneratedCtor(ctor)) {
return CompositeValue.create(classType); return CompositeValue.create(classType);
} else if (ctor == AGGREGATE_INITIALIZATION) { } else if (ctor == AGGREGATE_INITIALIZATION) {
// TODO(nathanridge): Support aggregate initialization. return CompositeValue.create(new EvalInitList(fArguments, getTemplateDefinition()),
return IntegralValue.UNKNOWN; classType, point);
} else if (ctor != null) { } else if (ctor != null) {
EvalConstructor evalCtor = new EvalConstructor(classType, (ICPPConstructor) ctor, EvalConstructor evalCtor = new EvalConstructor(classType, (ICPPConstructor) ctor,
fArguments, getTemplateDefinition()); fArguments, getTemplateDefinition());

View file

@ -89,7 +89,8 @@ public final class ExecDeclarator implements ICPPExecution {
return createPointerValue(record, context, computedInitializerEval); return createPointerValue(record, context, computedInitializerEval);
} else if (isArrayType(nestedType) && !isCStringType(nestedType)) { } else if (isArrayType(nestedType) && !isCStringType(nestedType)) {
if (computedInitializerEval instanceof EvalInitList) { if (computedInitializerEval instanceof EvalInitList) {
IValue value = CompositeValue.create((EvalInitList) computedInitializerEval, (IArrayType) (type)); IValue value = CompositeValue.create((EvalInitList) computedInitializerEval,
(IArrayType) type, context.getPoint());
return new EvalFixed(type, computedInitializerEval.getValueCategory(context.getPoint()), value); return new EvalFixed(type, computedInitializerEval.getValueCategory(context.getPoint()), value);
} else { } else {
// TODO(sprigogin): Should something else be done here? // TODO(sprigogin): Should something else be done here?