aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2011-11-01 15:53:09 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2011-11-01 15:53:09 +0000
commitcc7a6484d8afd6f8bede2757666c42248228e408 (patch)
tree16ac5bece6dd53151d4e15b0a57cf26c926b5f8f /lib/Sema/SemaOverload.cpp
parent885011b021d00a1604adcc311567526666b498c4 (diff)
Enable function call and some overload resolution with parameters of aggregate class type and initializer list arguments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143462 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp47
1 files changed, 40 insertions, 7 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index f5494dee17..153c0f8c24 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -305,7 +305,10 @@ void UserDefinedConversionSequence::DebugPrint() const {
Before.DebugPrint();
OS << " -> ";
}
- OS << '\'' << *ConversionFunction << '\'';
+ if (ConversionFunction)
+ OS << '\'' << *ConversionFunction << '\'';
+ else
+ OS << "aggregate initialization";
if (After.First || After.Second || After.Third) {
OS << " -> ";
After.DebugPrint();
@@ -2701,11 +2704,15 @@ CompareImplicitConversionSequences(Sema &S,
if (ICS1.getKind() != ICS2.getKind())
return ImplicitConversionSequence::Indistinguishable;
+ ImplicitConversionSequence::CompareKind Result =
+ ImplicitConversionSequence::Indistinguishable;
+
// Two implicit conversion sequences of the same form are
// indistinguishable conversion sequences unless one of the
// following rules apply: (C++ 13.3.3.2p3):
if (ICS1.isStandard())
- return CompareStandardConversionSequences(S, ICS1.Standard, ICS2.Standard);
+ Result = CompareStandardConversionSequences(S,
+ ICS1.Standard, ICS2.Standard);
else if (ICS1.isUserDefined()) {
// User-defined conversion sequence U1 is a better conversion
// sequence than another user-defined conversion sequence U2 if
@@ -2715,12 +2722,21 @@ CompareImplicitConversionSequences(Sema &S,
// U2 (C++ 13.3.3.2p3).
if (ICS1.UserDefined.ConversionFunction ==
ICS2.UserDefined.ConversionFunction)
- return CompareStandardConversionSequences(S,
- ICS1.UserDefined.After,
- ICS2.UserDefined.After);
+ Result = CompareStandardConversionSequences(S,
+ ICS1.UserDefined.After,
+ ICS2.UserDefined.After);
}
- return ImplicitConversionSequence::Indistinguishable;
+ // List-initialization sequence L1 is a better conversion sequence than
+ // list-initialization sequence L2 if L1 converts to std::initializer_list<X>
+ // for some X and L2 does not.
+ if (Result == ImplicitConversionSequence::Indistinguishable &&
+ ICS1.isListInitializationSequence() &&
+ ICS2.isListInitializationSequence()) {
+ // FIXME: Find out if ICS1 converts to initializer_list and ICS2 doesn't.
+ }
+
+ return Result;
}
static bool hasSimilarType(ASTContext &Context, QualType T1, QualType T2) {
@@ -3780,6 +3796,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
ImplicitConversionSequence Result;
Result.setBad(BadConversionSequence::no_conversion, From, ToType);
+ Result.setListInitializationSequence();
// C++11 [over.ics.list]p2:
// If the parameter type is std::initializer_list<X> or "array of X" and
@@ -3805,8 +3822,24 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
// Otherwise, if the parameter has an aggregate type which can be
// initialized from the initializer list [...] the implicit conversion
// sequence is a user-defined conversion sequence.
- // FIXME: Implement this.
if (ToType->isAggregateType()) {
+ // Type is an aggregate, argument is an init list. At this point it comes
+ // down to checking whether the initialization works.
+ // FIXME: Find out whether this parameter is consumed or not.
+ InitializedEntity Entity =
+ InitializedEntity::InitializeParameter(S.Context, ToType,
+ /*Consumed=*/false);
+ if (S.CanPerformCopyInitialization(Entity, S.Owned(From))) {
+ Result.setUserDefined();
+ Result.UserDefined.Before.setAsIdentityConversion();
+ // Initializer lists don't have a type.
+ Result.UserDefined.Before.setFromType(QualType());
+ Result.UserDefined.Before.setAllToTypes(QualType());
+
+ Result.UserDefined.After.setAsIdentityConversion();
+ Result.UserDefined.After.setFromType(ToType);
+ Result.UserDefined.After.setAllToTypes(ToType);
+ }
return Result;
}