CXXRecordDecl *T2RecordDecl
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
- QualType ToType
- = AllowRvalues? DeclType->getAs<ReferenceType>()->getPointeeType()
- : DeclType;
-
OverloadCandidateSet CandidateSet(DeclLoc);
const UnresolvedSetImpl *Conversions
= T2RecordDecl->getVisibleConversionFunctions();
if (ConvTemplate)
S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
- Init, ToType, CandidateSet);
+ Init, DeclType, CandidateSet);
else
S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
- ToType, CandidateSet);
+ DeclType, CandidateSet);
}
OverloadCandidateSet::iterator Best;
// of type "cv2 T2" as follows:
// -- If reference is an lvalue reference and the initializer expression
- // The next bullet point (T1 is a function) is pretty much equivalent to this
- // one, so it's handled here.
- if (!isRValRef || T1->isFunctionType()) {
+ if (!isRValRef) {
// -- is an lvalue (but is not a bit-field), and "cv1 T1" is
// reference-compatible with "cv2 T2," or
//
// -- Otherwise, the reference shall be an lvalue reference to a
// non-volatile const type (i.e., cv1 shall be const), or the reference
- // shall be an rvalue reference and the initializer expression shall be
- // an rvalue or have a function type.
+ // shall be an rvalue reference.
//
// We actually handle one oddity of C++ [over.ics.ref] at this
// point, which is that, due to p2 (which short-circuits reference
if (!isRValRef && !T1.isConstQualified())
return ICS;
- // -- If T1 is a function type, then
- // -- if T2 is the same type as T1, the reference is bound to the
- // initializer expression lvalue;
- // -- if T2 is a class type and the initializer expression can be
- // implicitly converted to an lvalue of type T1 [...], the
- // reference is bound to the function lvalue that is the result
- // of the conversion;
- // This is the same as for the lvalue case above, so it was handled there.
- // -- otherwise, the program is ill-formed.
- // This is the one difference to the lvalue case.
- if (T1->isFunctionType())
- return ICS;
-
- // -- Otherwise, if T2 is a class type and
- // -- the initializer expression is an rvalue and "cv1 T1"
- // is reference-compatible with "cv2 T2," or
+ // -- If the initializer expression
//
- // -- T1 is not reference-related to T2 and the initializer
- // expression can be implicitly converted to an rvalue
- // of type "cv3 T3" (this conversion is selected by
- // enumerating the applicable conversion functions
- // (13.3.1.6) and choosing the best one through overload
- // resolution (13.3)),
+ // -- is an xvalue, class prvalue, array prvalue or function
+ // lvalue and "cv1T1" is reference-compatible with "cv2 T2", or
+ if (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification &&
+ (InitCategory.isXValue() ||
+ (InitCategory.isPRValue() && (T2->isRecordType() || T2->isArrayType())) ||
+ (InitCategory.isLValue() && T2->isFunctionType()))) {
+ ICS.setStandard();
+ ICS.Standard.First = ICK_Identity;
+ ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
+ : ObjCConversion? ICK_Compatible_Conversion
+ : ICK_Identity;
+ ICS.Standard.Third = ICK_Identity;
+ ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
+ ICS.Standard.setToType(0, T2);
+ ICS.Standard.setToType(1, T1);
+ ICS.Standard.setToType(2, T1);
+ ICS.Standard.ReferenceBinding = true;
+ // In C++0x, this is always a direct binding. In C++98/03, it's a direct
+ // binding unless we're binding to a class prvalue.
+ // Note: Although xvalues wouldn't normally show up in C++98/03 code, we
+ // allow the use of rvalue references in C++98/03 for the benefit of
+ // standard library implementors; therefore, we need the xvalue check here.
+ ICS.Standard.DirectBinding =
+ S.getLangOptions().CPlusPlus0x ||
+ (InitCategory.isPRValue() && !T2->isRecordType());
+ ICS.Standard.RRefBinding = isRValRef;
+ ICS.Standard.CopyConstructor = 0;
+ return ICS;
+ }
+
+ // -- has a class type (i.e., T2 is a class type), where T1 is not
+ // reference-related to T2, and can be implicitly converted to
+ // an xvalue, class prvalue, or function lvalue of type
+ // "cv3 T3", where "cv1 T1" is reference-compatible with
+ // "cv3 T3",
//
- // then the reference is bound to the initializer
- // expression rvalue in the first case and to the object
- // that is the result of the conversion in the second case
- // (or, in either case, to the appropriate base class
- // subobject of the object).
- if (T2->isRecordType()) {
- // First case: "cv1 T1" is reference-compatible with "cv2 T2". This is a
- // direct binding in C++0x but not in C++03.
- if (InitCategory.isRValue() &&
- RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
- ICS.setStandard();
- ICS.Standard.First = ICK_Identity;
- ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
- : ObjCConversion? ICK_Compatible_Conversion
- : ICK_Identity;
- ICS.Standard.Third = ICK_Identity;
- ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
- ICS.Standard.setToType(0, T2);
- ICS.Standard.setToType(1, T1);
- ICS.Standard.setToType(2, T1);
- ICS.Standard.ReferenceBinding = true;
- ICS.Standard.DirectBinding = S.getLangOptions().CPlusPlus0x;
- ICS.Standard.RRefBinding = isRValRef;
- ICS.Standard.CopyConstructor = 0;
- return ICS;
- }
-
- // Second case: not reference-related.
- if (RefRelationship == Sema::Ref_Incompatible &&
- !S.RequireCompleteType(DeclLoc, T2, 0) &&
- FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
- Init, T2, /*AllowRvalues=*/true,
- AllowExplicit)) {
- // In the second case, if the reference is an rvalue reference
- // and the second standard conversion sequence of the
- // user-defined conversion sequence includes an lvalue-to-rvalue
- // conversion, the program is ill-formed.
- if (ICS.isUserDefined() && isRValRef &&
- ICS.UserDefined.After.First == ICK_Lvalue_To_Rvalue)
- ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType);
+ // then the reference is bound to the value of the initializer
+ // expression in the first case and to the result of the conversion
+ // in the second case (or, in either case, to an appropriate base
+ // class subobject).
+ if (!SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible &&
+ T2->isRecordType() && !S.RequireCompleteType(DeclLoc, T2, 0) &&
+ FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+ Init, T2, /*AllowRvalues=*/true,
+ AllowExplicit)) {
+ // In the second case, if the reference is an rvalue reference
+ // and the second standard conversion sequence of the
+ // user-defined conversion sequence includes an lvalue-to-rvalue
+ // conversion, the program is ill-formed.
+ if (ICS.isUserDefined() && isRValRef &&
+ ICS.UserDefined.After.First == ICK_Lvalue_To_Rvalue)
+ ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType);
- return ICS;
- }
+ return ICS;
}
// -- Otherwise, a temporary of type "cv1 T1" is created and