mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Bug 543038 - Addition to brace elision for aggregate init
- getNestedType for typedefs - check aggregate initialization in EvalTypeID Change-Id: I04ab2088c85373007312f7a419eb508ab53f69c8 Signed-off-by: Hannes Vogt <hannes@havogt.de>
This commit is contained in:
parent
c626ede917
commit
d42c60b651
4 changed files with 41 additions and 21 deletions
|
@ -12885,8 +12885,8 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
||||||
// }
|
// }
|
||||||
public void testBraceElisionForAggregateInit1_SimpleTooManyInitializers_543038() throws Exception {
|
public void testBraceElisionForAggregateInit1_SimpleTooManyInitializers_543038() throws Exception {
|
||||||
BindingAssertionHelper bh = getAssertionHelper();
|
BindingAssertionHelper bh = getAssertionHelper();
|
||||||
// bh.assertProblem("array{{1,2}}", 5); // TODO not implemented
|
bh.assertImplicitName("array{{1,2}}", 5, IProblemBinding.class);
|
||||||
// bh.assertProblem("array{1,2}", 5); // TODO not implemented
|
bh.assertImplicitName("array{1,2}", 5, IProblemBinding.class);
|
||||||
bh.assertImplicitName("a0", 2, IProblemBinding.class);
|
bh.assertImplicitName("a0", 2, IProblemBinding.class);
|
||||||
bh.assertProblem("foo({1,2})", 3);
|
bh.assertProblem("foo({1,2})", 3);
|
||||||
bh.assertProblem("foo({{1,2}})", 3);
|
bh.assertProblem("foo({{1,2}})", 3);
|
||||||
|
@ -12918,14 +12918,8 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
||||||
// }
|
// }
|
||||||
public void testBraceElisionForAggregateInit2_WithNonAggregate_543038() throws Exception {
|
public void testBraceElisionForAggregateInit2_WithNonAggregate_543038() throws Exception {
|
||||||
BindingAssertionHelper bh = getAssertionHelper();
|
BindingAssertionHelper bh = getAssertionHelper();
|
||||||
|
|
||||||
bh.assertNonProblem("foo({level1{{1,2}}})", 3);
|
bh.assertNonProblem("foo({level1{{1,2}}})", 3);
|
||||||
|
bh.assertImplicitName("level1{{1,2}};", 6, ICPPConstructor.class);
|
||||||
ICPPConstructor ctor = bh.assertNonProblem("level1(level0 a)", "level1");
|
|
||||||
ICPPASTSimpleTypeConstructorExpression typeConstructorExpr = bh.assertNode("level1{{1,2}};", "level1{{1,2}}");
|
|
||||||
IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) typeConstructorExpr).getImplicitNames();
|
|
||||||
assertEquals(ctor, implicitNames[0].resolveBinding());
|
|
||||||
|
|
||||||
bh.assertImplicitName("level1{1,2};", 6, IProblemBinding.class);
|
bh.assertImplicitName("level1{1,2};", 6, IProblemBinding.class);
|
||||||
bh.assertProblem("foo({{{1,2,3}}}", 3);
|
bh.assertProblem("foo({{{1,2,3}}}", 3);
|
||||||
}
|
}
|
||||||
|
@ -12989,4 +12983,24 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
||||||
bh.assertNonProblem("foo({{1,2,3,{1,2,3}}});", 3);
|
bh.assertNonProblem("foo({{1,2,3,{1,2,3}}});", 3);
|
||||||
bh.assertProblem("foo({{1,2,{1,2,3}}});", 3);
|
bh.assertProblem("foo({{1,2,{1,2,3}}});", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<typename T, int D>
|
||||||
|
// struct trait {
|
||||||
|
// using type = T[D];
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template<typename T, int D>
|
||||||
|
// struct array {
|
||||||
|
// typename trait<T, D>::type data;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// void foo(array<int, 1>) {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int main() {
|
||||||
|
// foo({1});
|
||||||
|
// }
|
||||||
|
public void testBraceElisionForAggregateInit6_typedef_543038() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,17 +60,18 @@ class AggregateInitialization {
|
||||||
* else recurses into the subaggregate.
|
* else recurses into the subaggregate.
|
||||||
*/
|
*/
|
||||||
private Cost checkElement(IType type, IValue initialValue, Cost worstCost) throws DOMException {
|
private Cost checkElement(IType type, IValue initialValue, Cost worstCost) throws DOMException {
|
||||||
|
IType nestedType = SemanticUtil.getNestedType(type, SemanticUtil.TDEF);
|
||||||
if (fIndex >= fInitializers.length)
|
if (fIndex >= fInitializers.length)
|
||||||
// TODO for arrays we could short-circuit default init instead of trying to init each element
|
// TODO for arrays we could short-circuit default init instead of trying to init each element
|
||||||
return checkInitializationFromDefaultMemberInitializer(type, initialValue, worstCost);
|
return checkInitializationFromDefaultMemberInitializer(nestedType, initialValue, worstCost);
|
||||||
worstCost = new Cost(fInitializers[fIndex].getType(), type, Rank.IDENTITY);
|
worstCost = new Cost(fInitializers[fIndex].getType(), nestedType, Rank.IDENTITY);
|
||||||
|
|
||||||
if (fInitializers[fIndex].isInitializerList() || !isAggregate(type)) { // no braces are elided
|
if (fInitializers[fIndex].isInitializerList() || !isAggregate(nestedType)) { // no braces are elided
|
||||||
// p3: The elements of the initializer list are taken as initializers for the elements
|
// p3: The elements of the initializer list are taken as initializers for the elements
|
||||||
// of the aggregate, in order.
|
// of the aggregate, in order.
|
||||||
ICPPEvaluation initializer = fInitializers[fIndex];
|
ICPPEvaluation initializer = fInitializers[fIndex];
|
||||||
fIndex++;
|
fIndex++;
|
||||||
Cost cost = Conversions.checkImplicitConversionSequence(type, initializer.getType(),
|
Cost cost = Conversions.checkImplicitConversionSequence(nestedType, initializer.getType(),
|
||||||
initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
|
initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
|
||||||
if (!cost.converts()) {
|
if (!cost.converts()) {
|
||||||
return cost;
|
return cost;
|
||||||
|
@ -84,7 +85,7 @@ class AggregateInitialization {
|
||||||
worstCost = cost;
|
worstCost = cost;
|
||||||
}
|
}
|
||||||
} else { // braces are elided: need to check on subaggregates
|
} else { // braces are elided: need to check on subaggregates
|
||||||
Cost cost = checkInitializationOfElements(type, worstCost);
|
Cost cost = checkInitializationOfElements(nestedType, worstCost);
|
||||||
if (!cost.converts())
|
if (!cost.converts())
|
||||||
return cost;
|
return cost;
|
||||||
if (cost.compareTo(worstCost) > 0) {
|
if (cost.compareTo(worstCost) > 0) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
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.cpp.ICPPBasicType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
|
@ -299,9 +300,14 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
if (binding instanceof ICPPFunction) {
|
if (binding instanceof ICPPFunction) {
|
||||||
return (ICPPFunction) binding;
|
return (ICPPFunction) binding;
|
||||||
}
|
}
|
||||||
// TODO check aggregate initialization
|
|
||||||
if (fUsesBracedInitList && allConstructorsAreCompilerGenerated(constructors)) {
|
if (fUsesBracedInitList && allConstructorsAreCompilerGenerated(constructors)) {
|
||||||
return AGGREGATE_INITIALIZATION;
|
Cost cost = AggregateInitialization.check(classType,
|
||||||
|
new EvalInitList(arguments, getTemplateDefinition()));
|
||||||
|
if (cost.converts())
|
||||||
|
return AGGREGATE_INITIALIZATION;
|
||||||
|
else
|
||||||
|
return new CPPFunction.CPPFunctionProblem(null, ISemanticProblem.BINDING_NOT_FOUND,
|
||||||
|
classType.getNameCharArray());
|
||||||
}
|
}
|
||||||
if (binding instanceof IProblemBinding && !(binding instanceof ICPPFunction))
|
if (binding instanceof IProblemBinding && !(binding instanceof ICPPFunction))
|
||||||
return new CPPFunction.CPPFunctionProblem(null, ((IProblemBinding) binding).getID(),
|
return new CPPFunction.CPPFunctionProblem(null, ((IProblemBinding) binding).getID(),
|
||||||
|
@ -309,11 +315,6 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check aggregate initialization
|
|
||||||
if (fUsesBracedInitList && allConstructorsAreCompilerGenerated(constructors)) {
|
|
||||||
return AGGREGATE_INITIALIZATION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitConstructor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitConstructor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
|
||||||
|
@ -267,6 +268,9 @@ public class TypeTraits {
|
||||||
* no base classes (Clause 10), and no virtual functions (10.3).
|
* no base classes (Clause 10), and no virtual functions (10.3).
|
||||||
*/
|
*/
|
||||||
public static boolean isAggregateClass(ICPPClassType classType) {
|
public static boolean isAggregateClass(ICPPClassType classType) {
|
||||||
|
// 8.1.5.1 p.2 (N4659): The closure type is not an aggregate type.
|
||||||
|
if (classType instanceof CPPClosureType)
|
||||||
|
return false;
|
||||||
if (classType.getBases().length > 0)
|
if (classType.getBases().length > 0)
|
||||||
return false;
|
return false;
|
||||||
ICPPMethod[] methods = classType.getDeclaredMethods();
|
ICPPMethod[] methods = classType.getDeclaredMethods();
|
||||||
|
|
Loading…
Add table
Reference in a new issue