aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-25 23:49:36 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-25 23:49:36 +0000
commit4d4feead7e240bf24264658b5abb0b88d52ed684 (patch)
tree258096989bf727e21e05f06a863b1a2af0c591d6
parentce95566b36a4ff16e90507633dad8b7a76572999 (diff)
Speculatively revert r124236
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124247 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/Overload.h22
-rw-r--r--lib/Sema/SemaOverload.cpp71
-rw-r--r--test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp6
3 files changed, 29 insertions, 70 deletions
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 4a7cb20e61..fa3c94b0ac 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -133,30 +133,24 @@ namespace clang {
/// Deprecated - Whether this the deprecated conversion of a
/// string literal to a pointer to non-const character data
/// (C++ 4.2p2).
- unsigned DeprecatedStringLiteralToCharPtr : 1;
+ bool DeprecatedStringLiteralToCharPtr : 1;
/// IncompatibleObjC - Whether this is an Objective-C conversion
/// that we should warn about (if we actually use it).
- unsigned IncompatibleObjC : 1;
+ bool IncompatibleObjC : 1;
/// ReferenceBinding - True when this is a reference binding
/// (C++ [over.ics.ref]).
- unsigned ReferenceBinding : 1;
+ bool ReferenceBinding : 1;
/// DirectBinding - True when this is a reference binding that is a
/// direct binding (C++ [dcl.init.ref]).
- unsigned DirectBinding : 1;
+ 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;
- /// \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.
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 602a118c3b..85ae6f7326 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -170,9 +170,7 @@ void StandardConversionSequence::setAsIdentityConversion() {
DeprecatedStringLiteralToCharPtr = false;
ReferenceBinding = false;
DirectBinding = false;
- IsLvalueReference = true;
- BindsToFunctionLvalue = false;
- BindsToRvalue = false;
+ RRefBinding = false;
CopyConstructor = 0;
}
@@ -2326,33 +2324,6 @@ compareStandardConversionSubsets(ASTContext &Context,
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).
@@ -2458,12 +2429,18 @@ CompareStandardConversionSequences(Sema &S,
return QualCK;
if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
- // 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++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;
+
// 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
@@ -2989,9 +2966,7 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
ICS.Standard.setToType(2, T1);
ICS.Standard.ReferenceBinding = true;
ICS.Standard.DirectBinding = true;
- ICS.Standard.IsLvalueReference = !isRValRef;
- ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
- ICS.Standard.BindsToRvalue = false;
+ ICS.Standard.RRefBinding = isRValRef && InitCategory.isRValue();
ICS.Standard.CopyConstructor = 0;
// Nothing more to do: the inaccessibility/ambiguity check for
@@ -3061,9 +3036,7 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
ICS.Standard.DirectBinding =
S.getLangOptions().CPlusPlus0x ||
(InitCategory.isPRValue() && !T2->isRecordType());
- ICS.Standard.IsLvalueReference = !isRValRef;
- ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
- ICS.Standard.BindsToRvalue = InitCategory.isRValue();
+ ICS.Standard.RRefBinding = isRValRef && InitCategory.isRValue();
ICS.Standard.CopyConstructor = 0;
return ICS;
}
@@ -3141,14 +3114,10 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
// Of course, that's still a reference binding.
if (ICS.isStandard()) {
ICS.Standard.ReferenceBinding = true;
- ICS.Standard.IsLvalueReference = !isRValRef;
- ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
- ICS.Standard.BindsToRvalue = true;
+ ICS.Standard.RRefBinding = isRValRef;
} else if (ICS.isUserDefined()) {
ICS.UserDefined.After.ReferenceBinding = true;
- ICS.Standard.IsLvalueReference = !isRValRef;
- ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
- ICS.Standard.BindsToRvalue = true;
+ ICS.UserDefined.After.RRefBinding = isRValRef;
}
return ICS;
@@ -3243,11 +3212,7 @@ TryObjectArgumentInitialization(Sema &S, QualType OrigFromType,
ICS.Standard.setAllToTypes(ImplicitParamType);
ICS.Standard.ReferenceBinding = true;
ICS.Standard.DirectBinding = true;
-
- // FIXME: Rvalue references.
- ICS.Standard.IsLvalueReference = true;
- ICS.Standard.BindsToFunctionLvalue = false;
- ICS.Standard.BindsToRvalue = false;
+ ICS.Standard.RRefBinding = false;
return ICS;
}
diff --git a/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp b/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp
index ab171bc3f6..faff058a50 100644
--- a/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp
+++ b/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp
@@ -50,10 +50,10 @@ struct remove_reference<T&&> {
};
namespace FunctionReferencesOverloading {
- template<typename T> int &f(typename remove_reference<T>::type&);
- template<typename T> float &f(typename remove_reference<T>::type&&);
+ 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)]}}
void test_f(int (&func_ref)(int)) {
- int &ir = f<int (&)(int)>(func_ref);
+ f<int (&)(int)>(func_ref); // expected-error{{call to 'f' is ambiguous}}
}
}