diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-20 16:44:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-20 16:44:54 +0000 |
commit | c5db24dfbc860a9fd1501c72f398bf6b6d5b6e0e (patch) | |
tree | 71b8c6c937ce9cd688ad52d6f0f3f2871c2d393e /lib/Sema/SemaInit.cpp | |
parent | 2e1c730167d2b978c66558c029d163ffe64b9656 (diff) |
Start refactoring reference binding to more closely match the C++0x
working paper's structure. The only functional change here is that we
now handling binding to array rvalues, which we would previously reject.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123918 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 69 |
1 files changed, 35 insertions, 34 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 9593489b80..7360eca1e9 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2597,13 +2597,17 @@ static void TryReferenceInitialization(Sema &S, return; } - // - [If T1 is not a function type], if T2 is a class type and - if (!T1Function && T2->isRecordType()) { - bool isXValue = InitCategory.isXValue(); - // - the initializer expression is an rvalue and "cv1 T1" is - // reference-compatible with "cv2 T2", or - if (InitCategory.isRValue() && - RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) { + // - If the initializer expression + // - is an xvalue, class prvalue, array prvalue, or function lvalue and + // "cv1 T1" is reference-compatible with "cv2 T2" + // Note: functions are handled below. + if (!T1Function && + RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification && + (InitCategory.isXValue() || + (InitCategory.isPRValue() && T2->isRecordType()) || + (InitCategory.isPRValue() && T2->isArrayType()))) { + ExprValueKind ValueKind = InitCategory.isXValue()? VK_XValue : VK_RValue; + if (InitCategory.isPRValue() && T2->isRecordType()) { // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the // compiler the freedom to perform a copy here or bind to the // object, while C++0x requires that we bind directly to the @@ -2615,27 +2619,30 @@ static void TryReferenceInitialization(Sema &S, // be callable whether or not the copy is actually done. if (!S.getLangOptions().CPlusPlus0x && !S.getLangOptions().Microsoft) Sequence.AddExtraneousCopyToTemporary(cv2T2); - - if (DerivedToBase) - Sequence.AddDerivedToBaseCastStep( - S.Context.getQualifiedType(T1, T2Quals), - isXValue ? VK_XValue : VK_RValue); - else if (ObjCConversion) - Sequence.AddObjCObjectConversionStep( - S.Context.getQualifiedType(T1, T2Quals)); - - if (T1Quals != T2Quals) - Sequence.AddQualificationConversionStep(cv1T1, - isXValue ? VK_XValue : VK_RValue); - Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/!isXValue); - return; } - - // - 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)), + + if (DerivedToBase) + Sequence.AddDerivedToBaseCastStep(S.Context.getQualifiedType(T1, T2Quals), + ValueKind); + else if (ObjCConversion) + Sequence.AddObjCObjectConversionStep( + S.Context.getQualifiedType(T1, T2Quals)); + + if (T1Quals != T2Quals) + Sequence.AddQualificationConversionStep(cv1T1, ValueKind); + Sequence.AddReferenceBindingStep(cv1T1, + /*bindingTemporary=*/(InitCategory.isPRValue() && !T2->isArrayType())); + return; + } + + // - 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", + // + // FIXME: Need to handle xvalue, class prvalue, etc. cases in + // TryRefInitWithConversionFunction. + if (T2->isRecordType()) { if (RefRelationship == Sema::Ref_Incompatible) { ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, Initializer, @@ -2652,13 +2659,7 @@ static void TryReferenceInitialization(Sema &S, Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers); return; } - - // - If the initializer expression is an rvalue, with T2 an array type, - // and "cv1 T1" is reference-compatible with "cv2 T2," the reference - // is bound to the object represented by the rvalue (see 3.10). - // FIXME: How can an array type be reference-compatible with anything? - // Don't we mean the element types of T1 and T2? - + // - Otherwise, a temporary of type “cv1 T1” is created and initialized // from the initializer expression using the rules for a non-reference // copy initialization (8.5). The reference is then bound to the |