]> granicus.if.org Git - clang/commitdiff
Rvalue references for *this: explicitly keep track of whether a
authorDouglas Gregor <dgregor@apple.com>
Wed, 26 Jan 2011 19:41:18 +0000 (19:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 26 Jan 2011 19:41:18 +0000 (19:41 +0000)
reference binding is for the implicit object parameter of a member
function with a ref-qualifier. My previous comment, that we didn't
need to track this explicitly, was wrong: we do in fact get
rvalue-references-prefer-rvalues overloading with ref-qualifiers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124313 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Overload.h
lib/Sema/SemaOverload.cpp
test/CXX/over/over.match/over.match.funcs/p4-0x.cpp

index 3d618689b2a4b3be2243b085cad4e3ee5a8c1744..fb7f5f129d4db6407a90496bd686e4716f9b985a 100644 (file)
@@ -157,6 +157,10 @@ namespace clang {
     /// \brief Whether we're binding to an rvalue.
     unsigned BindsToRvalue : 1;
     
+    /// \brief Whether this binds an implicit object argument to a 
+    /// non-static member function without a ref-qualifier.
+    unsigned BindsImplicitObjectArgumentWithoutRefQualifier : 1;
+    
     /// FromType - The type that this conversion is converting
     /// from. This is an opaque pointer that can be translated into a
     /// QualType.
index 62af5bb8fff695c22af5d0ffa4a262e42cdb0685..6d5eb8038db82f29fe3f926752e428f7f8b786ce 100644 (file)
@@ -173,6 +173,7 @@ void StandardConversionSequence::setAsIdentityConversion() {
   IsLvalueReference = true;
   BindsToFunctionLvalue = false;
   BindsToRvalue = false;
+  BindsImplicitObjectArgumentWithoutRefQualifier = false;
   CopyConstructor = 0;
 }
 
@@ -2344,11 +2345,10 @@ static bool isBetterReferenceBindingKind(const StandardConversionSequence &SCS1,
   // time of this writing) break the standard definition of std::forward
   // and std::reference_wrapper when dealing with references to functions.
   // Proposed wording changes submitted to CWG for consideration.
-  //
-  // Note: neither of these conditions will evalute true for the implicit 
-  // object parameter, because we don't set either BindsToRvalue or
-  // BindsToFunctionLvalue when computing the conversion sequence for the
-  // implicit object parameter.
+  if (SCS1.BindsImplicitObjectArgumentWithoutRefQualifier ||
+      SCS2.BindsImplicitObjectArgumentWithoutRefQualifier)
+    return false;
+  
   return (!SCS1.IsLvalueReference && SCS1.BindsToRvalue &&
           SCS2.IsLvalueReference) ||
          (SCS1.IsLvalueReference && SCS1.BindsToFunctionLvalue &&
@@ -2994,6 +2994,7 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
       ICS.Standard.IsLvalueReference = !isRValRef;
       ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
       ICS.Standard.BindsToRvalue = false;
+      ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
       ICS.Standard.CopyConstructor = 0;
 
       // Nothing more to do: the inaccessibility/ambiguity check for
@@ -3066,6 +3067,7 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
     ICS.Standard.IsLvalueReference = !isRValRef;
     ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
     ICS.Standard.BindsToRvalue = InitCategory.isRValue();        
+    ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
     ICS.Standard.CopyConstructor = 0;
     return ICS; 
   }
@@ -3146,11 +3148,13 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
     ICS.Standard.IsLvalueReference = !isRValRef;
     ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
     ICS.Standard.BindsToRvalue = true;
+    ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
   } else if (ICS.isUserDefined()) {
     ICS.UserDefined.After.ReferenceBinding = true;
     ICS.Standard.IsLvalueReference = !isRValRef;
     ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
     ICS.Standard.BindsToRvalue = true;
+    ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
   }
 
   return ICS;
@@ -3286,9 +3290,9 @@ TryObjectArgumentInitialization(Sema &S, QualType OrigFromType,
   ICS.Standard.DirectBinding = true;
   ICS.Standard.IsLvalueReference = Method->getRefQualifier() != RQ_RValue; 
   ICS.Standard.BindsToFunctionLvalue = false;
-  
-  // Note: we intentionally don't set this; see isBetterReferenceBindingKind().
-  ICS.Standard.BindsToRvalue = false;
+  ICS.Standard.BindsToRvalue = FromClassification.isRValue();
+  ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier
+    = (Method->getRefQualifier() == RQ_None);
   return ICS;
 }
 
index 855895af98e98144668c0ce764453979a84ec1ad..8ccc5b6204d059f12a2f2469a626ec3c0ecc13d3 100644 (file)
@@ -27,6 +27,8 @@ struct X0 {
 
   int &h() const&;
   float &h() &&;
+  int &h2() const&;
+  float &h2() const&&;
 };
 
 void X0::g() {
@@ -62,4 +64,7 @@ void test_ref_qualifier_overloading() {
   int &ir1 = lvalue<X0>().h();
   float &fr1 = xvalue<X0>().h();
   float &fr2 = prvalue<X0>().h();
+  int &ir2 = lvalue<X0>().h2();
+  float &fr3 = xvalue<X0>().h2();
+  float &fr4 = prvalue<X0>().h2();
 }