[cfe-commits] r124290 - in /cfe/trunk: include/clang/Sema/Overload.h lib/Sema/SemaOverload.cpp test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp

Douglas Gregor dgregor at apple.com
Wed Jan 26 06:52:12 PST 2011


Author: dgregor
Date: Wed Jan 26 08:52:12 2011
New Revision: 124290

URL: http://llvm.org/viewvc/llvm-project?rev=124290&view=rev
Log:
Reinstate r124236 (tweaking the rvalue-reference overload resolution
rules), now that we've actually have a clean build for me to sully.

Modified:
    cfe/trunk/include/clang/Sema/Overload.h
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp

Modified: cfe/trunk/include/clang/Sema/Overload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Overload.h?rev=124290&r1=124289&r2=124290&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Overload.h (original)
+++ cfe/trunk/include/clang/Sema/Overload.h Wed Jan 26 08:52:12 2011
@@ -133,24 +133,30 @@
     /// Deprecated - Whether this the deprecated conversion of a
     /// string literal to a pointer to non-const character data
     /// (C++ 4.2p2).
-    bool DeprecatedStringLiteralToCharPtr : 1;
+    unsigned DeprecatedStringLiteralToCharPtr : 1;
 
     /// IncompatibleObjC - Whether this is an Objective-C conversion
     /// that we should warn about (if we actually use it).
-    bool IncompatibleObjC : 1;
+    unsigned IncompatibleObjC : 1;
 
     /// ReferenceBinding - True when this is a reference binding
     /// (C++ [over.ics.ref]).
-    bool ReferenceBinding : 1;
+    unsigned ReferenceBinding : 1;
 
     /// DirectBinding - True when this is a reference binding that is a
     /// direct binding (C++ [dcl.init.ref]).
-    bool DirectBinding : 1;
-
-    /// RRefBinding - True when this is a reference binding of an rvalue
-    /// reference to an rvalue (C++0x [over.ics.rank]p3b4).
-    bool RRefBinding : 1;
+    unsigned DirectBinding : 1;
 
+    /// \brief Whether this is an lvalue reference binding (otherwise, it's
+    /// an rvalue reference binding).
+    unsigned IsLvalueReference : 1;
+    
+    /// \brief Whether we're binding to a function lvalue.
+    unsigned BindsToFunctionLvalue : 1;
+    
+    /// \brief Whether we're binding to an rvalue.
+    unsigned BindsToRvalue : 1;
+    
     /// FromType - The type that this conversion is converting
     /// from. This is an opaque pointer that can be translated into a
     /// QualType.

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=124290&r1=124289&r2=124290&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Jan 26 08:52:12 2011
@@ -170,7 +170,9 @@
   DeprecatedStringLiteralToCharPtr = false;
   ReferenceBinding = false;
   DirectBinding = false;
-  RRefBinding = false;
+  IsLvalueReference = true;
+  BindsToFunctionLvalue = false;
+  BindsToRvalue = false;
   CopyConstructor = 0;
 }
 
@@ -2324,6 +2326,33 @@
   return ImplicitConversionSequence::Indistinguishable;
 }
 
+/// \brief Determine whether one of the given reference bindings is better
+/// than the other based on what kind of bindings they are.
+static bool isBetterReferenceBindingKind(const StandardConversionSequence &SCS1,
+                                       const StandardConversionSequence &SCS2) {
+  // C++0x [over.ics.rank]p3b4:
+  //   -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
+  //      implicit object parameter of a non-static member function declared
+  //      without a ref-qualifier, and *either* S1 binds an rvalue reference 
+  //      to an rvalue and S2 binds an lvalue reference *or S1 binds an
+  //      lvalue reference to a function lvalue and S2 binds an rvalue 
+  //      reference*.
+  //
+  // FIXME: Rvalue references. We're going rogue with the above edits,
+  // because the semantics in the current C++0x working paper (N3225 at the
+  // 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.
+  //
+  // FIXME: Rvalue references. We don't know if we're dealing with the 
+  // implicit object parameter, or if the member function in this case has a 
+  // ref qualifier. (Of course, we don't have ref qualifiers yet.)
+  return (!SCS1.IsLvalueReference && SCS1.BindsToRvalue &&
+          SCS2.IsLvalueReference) ||
+         (SCS1.IsLvalueReference && SCS1.BindsToFunctionLvalue &&
+          !SCS2.IsLvalueReference);
+}
+  
 /// CompareStandardConversionSequences - Compare two standard
 /// conversion sequences to determine whether one is better than the
 /// other or if they are indistinguishable (C++ 13.3.3.2p3).
@@ -2429,18 +2458,12 @@
     return QualCK;
 
   if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
-    // C++0x [over.ics.rank]p3b4:
-    //   -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
-    //      implicit object parameter of a non-static member function declared
-    //      without a ref-qualifier, and S1 binds an rvalue reference to an
-    //      rvalue and S2 binds an lvalue reference.
-    // FIXME: Rvalue references. We don't know if we're dealing with the 
-    // implicit object parameter, or if the member function in this case has a 
-    // ref qualifier. (Of course, we don't have ref qualifiers yet.)
-    if (SCS1.RRefBinding != SCS2.RRefBinding)
-      return SCS1.RRefBinding ? ImplicitConversionSequence::Better
-                              : ImplicitConversionSequence::Worse;
-
+    // Check for a better reference binding based on the kind of bindings.
+    if (isBetterReferenceBindingKind(SCS1, SCS2))
+      return ImplicitConversionSequence::Better;
+    else if (isBetterReferenceBindingKind(SCS2, SCS1))
+      return ImplicitConversionSequence::Worse;
+    
     // C++ [over.ics.rank]p3b4:
     //   -- S1 and S2 are reference bindings (8.5.3), and the types to
     //      which the references refer are the same type except for
@@ -2966,7 +2989,9 @@
       ICS.Standard.setToType(2, T1);
       ICS.Standard.ReferenceBinding = true;
       ICS.Standard.DirectBinding = true;
-      ICS.Standard.RRefBinding = isRValRef && InitCategory.isRValue();
+      ICS.Standard.IsLvalueReference = !isRValRef;
+      ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
+      ICS.Standard.BindsToRvalue = false;
       ICS.Standard.CopyConstructor = 0;
 
       // Nothing more to do: the inaccessibility/ambiguity check for
@@ -3036,7 +3061,9 @@
     ICS.Standard.DirectBinding = 
       S.getLangOptions().CPlusPlus0x || 
       (InitCategory.isPRValue() && !T2->isRecordType());
-    ICS.Standard.RRefBinding = isRValRef && InitCategory.isRValue();
+    ICS.Standard.IsLvalueReference = !isRValRef;
+    ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
+    ICS.Standard.BindsToRvalue = InitCategory.isRValue();        
     ICS.Standard.CopyConstructor = 0;
     return ICS; 
   }
@@ -3114,10 +3141,14 @@
   // Of course, that's still a reference binding.
   if (ICS.isStandard()) {
     ICS.Standard.ReferenceBinding = true;
-    ICS.Standard.RRefBinding = isRValRef;
+    ICS.Standard.IsLvalueReference = !isRValRef;
+    ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
+    ICS.Standard.BindsToRvalue = true;
   } else if (ICS.isUserDefined()) {
     ICS.UserDefined.After.ReferenceBinding = true;
-    ICS.UserDefined.After.RRefBinding = isRValRef;
+    ICS.Standard.IsLvalueReference = !isRValRef;
+    ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
+    ICS.Standard.BindsToRvalue = true;
   }
 
   return ICS;
@@ -3212,7 +3243,11 @@
   ICS.Standard.setAllToTypes(ImplicitParamType);
   ICS.Standard.ReferenceBinding = true;
   ICS.Standard.DirectBinding = true;
-  ICS.Standard.RRefBinding = false;
+  
+  // FIXME: Rvalue references.
+  ICS.Standard.IsLvalueReference = true; 
+  ICS.Standard.BindsToFunctionLvalue = false;
+  ICS.Standard.BindsToRvalue = false;
   return ICS;
 }
 

Modified: cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp?rev=124290&r1=124289&r2=124290&view=diff
==============================================================================
--- cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp (original)
+++ cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp Wed Jan 26 08:52:12 2011
@@ -50,10 +50,10 @@
 };
 
 namespace FunctionReferencesOverloading {
-  template<typename T> int &f(typename remove_reference<T>::type&); // expected-note{{candidate function [with T = int (&)(int)]}}
-  template<typename T> float &f(typename remove_reference<T>::type&&); // expected-note{{candidate function [with T = int (&)(int)]}}
+  template<typename T> int &f(typename remove_reference<T>::type&);
+  template<typename T> float &f(typename remove_reference<T>::type&&);
 
   void test_f(int (&func_ref)(int)) {
-    f<int (&)(int)>(func_ref); // expected-error{{call to 'f' is ambiguous}}
+    int &ir = f<int (&)(int)>(func_ref);
   }
 }





More information about the cfe-commits mailing list