From 286e04711a19411f8ade68be2dddb94d7891407e Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Fri, 12 Mar 2010 14:49:49 +0000 Subject: [PATCH] Bug 302412: Direct list initialization. --- .../core/parser/tests/ast2/AST2CPPTests.java | 2 +- .../parser/cpp/semantics/CPPSemantics.java | 30 ++++++++++--------- .../dom/parser/cpp/semantics/Conversions.java | 14 ++++----- .../core/dom/parser/cpp/semantics/Cost.java | 4 +++ .../parser/cpp/semantics/FunctionCost.java | 5 ++-- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 3bd7f859a0d..fb9255df6d5 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -8110,7 +8110,7 @@ public class AST2CPPTests extends AST2BaseTest { // fs({1,2,3}); // fs({1.0,2.0,3.0}); // } - public void _testListInitialization_302412a() throws Exception { + public void testListInitialization_302412a() throws Exception { String code= getAboveComment(); parseAndCheckBindings(code, ParserLanguage.CPP); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index f6a153de62e..1621e70ba0b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -528,21 +528,23 @@ public class CPPSemantics { return false; } - public static IBinding selectConstructor(ICPPClassType classTarget, ICPPASTInitializerList initializerList) { - LookupData data= new LookupData(); - IASTName name = new CPPASTName(classTarget.getNameCharArray()); - name.setParent(initializerList); - name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY); - data.setFunctionArguments(initializerList); - try { - return CPPSemantics.selectConstructor(classTarget, data); - } catch (DOMException e) { - return e.getProblem(); - } - } - private static IBinding selectConstructor(ICPPClassType cls, LookupData data) throws DOMException { - // Force resolution of constructor bindings + final IType[] types = data.getFunctionArgumentTypes(); + if (types != null && types.length == 1 && types[0] instanceof InitializerListType) { + Cost cost= Conversions.listInitializationSequence((InitializerListType) types[0], cls, UDCMode.allowUDC, true); + if (cost.converts()) { + if (cost.isAmbiguousUDC()) { + return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, cls.getConstructors()); + } + IBinding result= cost.getUserDefinedConversion(); + if (result == null) { + return cls; + } + return result; + } + return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, cls.getConstructors()); + } + final ICPPConstructor[] constructors= cls.getConstructors(); if (constructors.length > 0) { data.foundItems= constructors; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 8c607c9d1b5..2836e42855e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -272,7 +272,7 @@ public class Conversions { private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException { if (source instanceof InitializerListType) { - return listInitializationSequence(((InitializerListType) source), target, udc); + return listInitializationSequence(((InitializerListType) source), target, udc, false); } // [13.3.3.1-6] Subsume cv-qualifications IType uqSource= SemanticUtil.getNestedType(source, TDEF | ALLCVQ); @@ -280,13 +280,13 @@ public class Conversions { if (cost.converts() || udc == UDCMode.noUDC) return cost; - return checkUserDefinedConversionSequence(sourceIsLValue, source, target, udc == UDCMode.deferUDC); + return checkUserDefinedConversionSequence(sourceIsLValue, source, target, udc == UDCMode.deferUDC, false); } /** * 13.3.3.1.5 List-initialization sequence [over.ics.list] */ - private static Cost listInitializationSequence(InitializerListType arg, IType target, UDCMode udc) throws DOMException { + static Cost listInitializationSequence(InitializerListType arg, IType target, UDCMode udc, boolean isDirect) throws DOMException { IType listType= getInitListType(target); if (listType != null) { IType[] exprTypes= arg.getExpressionTypes(); @@ -319,7 +319,7 @@ public class Conversions { cost.setUserDefinedConversion(null); return cost; } - return checkUserDefinedConversionSequence(false, arg, target, udc == UDCMode.deferUDC); + return checkUserDefinedConversionSequence(false, arg, target, udc == UDCMode.deferUDC, isDirect); } IASTInitializerClause[] args = arg.getInitializerList().getClauses(); @@ -508,7 +508,7 @@ public class Conversions { /** * [13.3.3.1.2] User-defined conversions */ - static final Cost checkUserDefinedConversionSequence(boolean sourceIsLValue, IType source, IType target, boolean deferUDC) throws DOMException { + static final Cost checkUserDefinedConversionSequence(boolean sourceIsLValue, IType source, IType target, boolean deferUDC, boolean isDirect) throws DOMException { IType s= getNestedType(source, TDEF | CVTYPE | REF); IType t= getNestedType(target, TDEF | CVTYPE | REF); @@ -525,7 +525,7 @@ public class Conversions { if (t instanceof ICPPClassType) { if (s instanceof InitializerListType) { // 13.3.1.7 Initialization by list-initialization - return listInitializationOfClass((InitializerListType) s, (ICPPClassType) t, false); + return listInitializationOfClass((InitializerListType) s, (ICPPClassType) t, isDirect); } // 13.3.1.4 Copy initialization of class by user-defined conversion return copyInitalizationOfClass(sourceIsLValue, source, s, target, (ICPPClassType) t); @@ -552,7 +552,7 @@ public class Conversions { final IType target = parTypes[0]; if (getInitListType(target) != null) { hasInitListConstructor= true; - Cost cost= listInitializationSequence(arg, target, UDCMode.noUDC); + Cost cost= listInitializationSequence(arg, target, UDCMode.noUDC, isDirect); if (cost.converts()) { int cmp= cost.compareTo(bestCost); if (bestCost == null || cmp < 0) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java index 7625acfa24d..5f6c34b4eae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java @@ -150,6 +150,10 @@ class Cost { fCouldNarrow= false; } + public ICPPFunction getUserDefinedConversion() { + return fUserDefinedConversion; + } + /** * Returns an integer < 0 if other cost is null, or this cost is smaller than the other cost, * 0 if this cost is equal to the other cost, diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java index f6943fc6f95..f17abd145ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java @@ -77,8 +77,9 @@ class FunctionCost { for (int i = 0; i < fCosts.length; i++) { Cost cost = fCosts[i]; if (cost.isDeferredUDC()) { - Cost udcCost= Conversions.checkUserDefinedConversionSequence(fSourceIsLValue.get(i), cost.source, cost.target, false); - fCosts[i]= udcCost; + Cost udcCost = Conversions.checkUserDefinedConversionSequence(fSourceIsLValue.get(i), + cost.source, cost.target, false, false); + fCosts[i] = udcCost; if (!udcCost.converts()) { return false; }