mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 09:16:02 +02:00
Bug 458679 - Ranking list-initialization sequences with user-defined
conversions Change-Id: Ia976acf656f3431f96880b32fedc575a56c4e86b Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
3cf7241ccb
commit
9ca379e67f
5 changed files with 69 additions and 37 deletions
|
@ -8778,6 +8778,30 @@ public class AST2CPPTests extends AST2TestBase {
|
||||||
helper.assertProblem("waldo({1, 2, 3, 4})", "waldo", IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
|
helper.assertProblem("waldo({1, 2, 3, 4})", "waldo", IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// namespace std {
|
||||||
|
// template<class E>
|
||||||
|
// class initializer_list {
|
||||||
|
// const E* _array;
|
||||||
|
// long unsigned int _len;
|
||||||
|
//
|
||||||
|
// initializer_list(const E* array, int len) {}
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// template<typename T>
|
||||||
|
// struct A {
|
||||||
|
// A(std::initializer_list<T> list) {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct B {
|
||||||
|
// int b;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// A<B> waldo({{0}, {0}});
|
||||||
|
public void testListInitialization_458679() throws Exception {
|
||||||
|
parseAndCheckImplicitNameBindings();
|
||||||
|
}
|
||||||
|
|
||||||
// namespace std {
|
// namespace std {
|
||||||
// template<typename T> class initializer_list;
|
// template<typename T> class initializer_list;
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -128,14 +128,6 @@ public class AST2TemplateTests extends AST2TestBase {
|
||||||
return parseAndCheckBindings(code, CPP);
|
return parseAndCheckBindings(code, CPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IASTTranslationUnit parseAndCheckImplicitNameBindings() throws Exception {
|
|
||||||
IASTTranslationUnit tu = parse(getAboveComment(), CPP, false, true);
|
|
||||||
NameCollector col = new NameCollector(true /* Visit implicit names */);
|
|
||||||
tu.accept(col);
|
|
||||||
assertNoProblemBindings(col);
|
|
||||||
return tu;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected BindingAssertionHelper getAssertionHelper() throws ParserException, IOException {
|
protected BindingAssertionHelper getAssertionHelper() throws ParserException, IOException {
|
||||||
String code= getAboveComment();
|
String code= getAboveComment();
|
||||||
return new BindingAssertionHelper(code, true);
|
return new BindingAssertionHelper(code, true);
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||||
|
|
||||||
|
import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -775,6 +777,14 @@ public class AST2TestBase extends BaseTestCase {
|
||||||
assertNoProblemBindings(col);
|
assertNoProblemBindings(col);
|
||||||
return tu;
|
return tu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final protected IASTTranslationUnit parseAndCheckImplicitNameBindings() throws Exception {
|
||||||
|
IASTTranslationUnit tu = parse(getAboveComment(), CPP, false, true);
|
||||||
|
NameCollector col = new NameCollector(true /* Visit implicit names */);
|
||||||
|
tu.accept(col);
|
||||||
|
assertNoProblemBindings(col);
|
||||||
|
return tu;
|
||||||
|
}
|
||||||
|
|
||||||
final protected void assertNoProblemBindings(NameCollector col) {
|
final protected void assertNoProblemBindings(NameCollector col) {
|
||||||
for (IASTName n : col.nameList) {
|
for (IASTName n : col.nameList) {
|
||||||
|
|
|
@ -601,6 +601,11 @@ public class Conversions {
|
||||||
bestCost.setRank(Rank.NO_MATCH);
|
bestCost.setRank(Rank.NO_MATCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// This cost came from listInitializationSequence() with an std::initializer_list
|
||||||
|
// type as the list initialization target. From the point of view of the caller,
|
||||||
|
// however, the target is the class type, not std::initializer_list, so update it
|
||||||
|
// accordingly.
|
||||||
|
bestCost.setListInitializationTarget(t);
|
||||||
return bestCost;
|
return bestCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,6 +200,35 @@ public class Cost {
|
||||||
if (cmp != 0)
|
if (cmp != 0)
|
||||||
return cmp;
|
return cmp;
|
||||||
|
|
||||||
|
// [over.ics.rank] p3.3:
|
||||||
|
// List-initialization sequence L1 is a better conversion sequence than
|
||||||
|
// list-initialization sequence L2 if
|
||||||
|
if (fListInitializationTarget != null && other.fListInitializationTarget != null) {
|
||||||
|
// - L1 converts to std::initializer_list<X> for some X and L2 does not,
|
||||||
|
// or if not that,
|
||||||
|
IType initListType = Conversions.getInitListType(fListInitializationTarget);
|
||||||
|
IType otherInitListType = Conversions.getInitListType(other.fListInitializationTarget);
|
||||||
|
if (initListType != null && otherInitListType == null) {
|
||||||
|
return -1;
|
||||||
|
} else if (initListType == null && otherInitListType != null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - L1 converts to type "array of N1 T", L2 converts to type "array of
|
||||||
|
// N2 T", and N1 is smaller than N2
|
||||||
|
if (fListInitializationTarget instanceof IArrayType && other.fListInitializationTarget instanceof IArrayType) {
|
||||||
|
IArrayType arrayType = (IArrayType) fListInitializationTarget;
|
||||||
|
IArrayType otherArrayType = (IArrayType) other.fListInitializationTarget;
|
||||||
|
if (arrayType.getType().isSameType(otherArrayType.getType())) {
|
||||||
|
Long size = arrayType.getSize().numericalValue();
|
||||||
|
Long otherSize = otherArrayType.getSize().numericalValue();
|
||||||
|
if (size != null && otherSize != null) {
|
||||||
|
return size.compareTo(otherSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// rank is equal
|
// rank is equal
|
||||||
if (rank == Rank.USER_DEFINED_CONVERSION) {
|
if (rank == Rank.USER_DEFINED_CONVERSION) {
|
||||||
// 13.3.3.1.10
|
// 13.3.3.1.10
|
||||||
|
@ -241,35 +270,7 @@ public class Cost {
|
||||||
if ((other.fQualificationAdjustments & qdiff) == 0)
|
if ((other.fQualificationAdjustments & qdiff) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [over.ics.rank] p3:
|
|
||||||
// List-initialization sequence L1 is a better conversion sequence than
|
|
||||||
// list-initialization sequence L2 if
|
|
||||||
if (fListInitializationTarget != null && other.fListInitializationTarget != null) {
|
|
||||||
// - L1 converts to std::initializer_list<X> for some X and L2 does not,
|
|
||||||
// or if not that,
|
|
||||||
IType initListType = Conversions.getInitListType(fListInitializationTarget);
|
|
||||||
IType otherInitListType = Conversions.getInitListType(other.fListInitializationTarget);
|
|
||||||
if (initListType != null && otherInitListType == null) {
|
|
||||||
return -1;
|
|
||||||
} else if (initListType == null && otherInitListType != null) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - L1 converts to type "array of N1 T", L2 converts to type "array of
|
|
||||||
// N2 T", and N1 is smaller than N2
|
|
||||||
if (fListInitializationTarget instanceof IArrayType && other.fListInitializationTarget instanceof IArrayType) {
|
|
||||||
IArrayType arrayType = (IArrayType) fListInitializationTarget;
|
|
||||||
IArrayType otherArrayType = (IArrayType) other.fListInitializationTarget;
|
|
||||||
if (arrayType.getType().isSameType(otherArrayType.getType())) {
|
|
||||||
Long size = arrayType.getSize().numericalValue();
|
|
||||||
Long otherSize = otherArrayType.getSize().numericalValue();
|
|
||||||
if (size != null && otherSize != null) {
|
|
||||||
return size.compareTo(otherSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue