diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-04-12 17:16:29 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-04-12 17:16:29 +0000 |
commit | e2b6833d445c7a4ce64f1816c05f176ba1740aca (patch) | |
tree | 654e1620b4b2022776410b7c16c044fbdfe3af35 /lib/Sema/SemaOverload.cpp | |
parent | 36dc958556adb36efd060a2773e026727005e3a8 (diff) |
Parse deleted member functions. Parsing member declarations goes through a different code path that I forgot previously.
Implement the rvalue reference overload dance for returning local objects. Returning a local object first tries to find a move constructor now.
The error message when no move constructor is defined (or is not applicable) and the copy constructor is deleted is quite ugly, though.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68902 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 875a38253d..70c9ee7ef9 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -376,17 +376,20 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD, /// not permitted. /// If @p AllowExplicit, then explicit user-defined conversions are /// permitted. +/// If @p ForceRValue, then overloading is performed as if From was an rvalue, +/// no matter its actual lvalueness. ImplicitConversionSequence Sema::TryImplicitConversion(Expr* From, QualType ToType, bool SuppressUserConversions, - bool AllowExplicit) + bool AllowExplicit, bool ForceRValue) { ImplicitConversionSequence ICS; if (IsStandardConversion(From, ToType, ICS.Standard)) ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; else if (getLangOptions().CPlusPlus && IsUserDefinedConversion(From, ToType, ICS.UserDefined, - !SuppressUserConversions, AllowExplicit)) { + !SuppressUserConversions, AllowExplicit, + ForceRValue)) { ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion; // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class @@ -1313,10 +1316,13 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) /// \param AllowExplicit true if the conversion should consider C++0x /// "explicit" conversion functions as well as non-explicit conversion /// functions (C++0x [class.conv.fct]p2). +/// +/// \param ForceRValue true if the expression should be treated as an rvalue +/// for overload resolution. bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, UserDefinedConversionSequence& User, bool AllowConversionFunctions, - bool AllowExplicit) + bool AllowExplicit, bool ForceRValue) { OverloadCandidateSet CandidateSet; if (const RecordType *ToRecordType = ToType->getAsRecordType()) { @@ -1340,7 +1346,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); if (Constructor->isConvertingConstructor()) AddOverloadCandidate(Constructor, &From, 1, CandidateSet, - /*SuppressUserConversions=*/true); + /*SuppressUserConversions=*/true, ForceRValue); } } } @@ -1856,24 +1862,29 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1, /// sequence required to pass this argument, which may be a bad /// conversion sequence (meaning that the argument cannot be passed to /// a parameter of this type). If @p SuppressUserConversions, then we -/// do not permit any user-defined conversion sequences. +/// do not permit any user-defined conversion sequences. If @p ForceRValue, +/// then we treat @p From as an rvalue, even if it is an lvalue. ImplicitConversionSequence Sema::TryCopyInitialization(Expr *From, QualType ToType, - bool SuppressUserConversions) { + bool SuppressUserConversions, bool ForceRValue) { if (ToType->isReferenceType()) { ImplicitConversionSequence ICS; - CheckReferenceInit(From, ToType, &ICS, SuppressUserConversions); + CheckReferenceInit(From, ToType, &ICS, SuppressUserConversions, + /*AllowExplicit=*/false, ForceRValue); return ICS; } else { - return TryImplicitConversion(From, ToType, SuppressUserConversions); + return TryImplicitConversion(From, ToType, SuppressUserConversions, + ForceRValue); } } -/// PerformArgumentPassing - Pass the argument Arg into a parameter of -/// type ToType. Returns true (and emits a diagnostic) if there was -/// an error, returns false if the initialization succeeded. +/// PerformCopyInitialization - Copy-initialize an object of type @p ToType with +/// the expression @p From. Returns true (and emits a diagnostic) if there was +/// an error, returns false if the initialization succeeded. Elidable should +/// be true when the copy may be elided (C++ 12.8p15). Overload resolution works +/// differently in C++0x for this case. bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType, - const char* Flavor) { + const char* Flavor, bool Elidable) { if (!getLangOptions().CPlusPlus) { // In C, argument passing is the same as performing an assignment. QualType FromType = From->getType(); @@ -1883,13 +1894,14 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType, return DiagnoseAssignmentResult(ConvTy, From->getLocStart(), ToType, FromType, From, Flavor); } - + if (ToType->isReferenceType()) return CheckReferenceInit(From, ToType); - if (!PerformImplicitConversion(From, ToType, Flavor)) + if (!PerformImplicitConversion(From, ToType, Flavor, + /*AllowExplicit=*/false, Elidable)) return false; - + return Diag(From->getSourceRange().getBegin(), diag::err_typecheck_convert_incompatible) << ToType << From->getType() << Flavor << From->getSourceRange(); @@ -1997,11 +2009,15 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) { /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined /// conversions via constructors or conversion operators. +/// If @p ForceRValue, treat all arguments as rvalues. This is a slightly +/// hacky way to implement the overloading rules for elidable copy +/// initialization in C++0x (C++0x 12.8p15). void Sema::AddOverloadCandidate(FunctionDecl *Function, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions) + bool SuppressUserConversions, + bool ForceRValue) { const FunctionProtoType* Proto = dyn_cast<FunctionProtoType>(Function->getType()->getAsFunctionType()); @@ -2017,7 +2033,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // function, e.g., X::f(). We use a NULL object as the implied // object argument (C++ [over.call.func]p3). AddMethodCandidate(Method, 0, Args, NumArgs, CandidateSet, - SuppressUserConversions); + SuppressUserConversions, ForceRValue); return; } @@ -2064,7 +2080,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, QualType ParamType = Proto->getArgType(ArgIdx); Candidate.Conversions[ArgIdx] = TryCopyInitialization(Args[ArgIdx], ParamType, - SuppressUserConversions); + SuppressUserConversions, ForceRValue); if (Candidate.Conversions[ArgIdx].ConversionKind == ImplicitConversionSequence::BadConversion) { Candidate.Viable = false; @@ -2099,12 +2115,14 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions, /// @c o.f(a1,a2), @c Object will contain @c o and @c Args will contain /// both @c a1 and @c a2. If @p SuppressUserConversions, then don't /// allow user-defined conversions via constructors or conversion -/// operators. +/// operators. If @p ForceRValue, treat all arguments as rvalues. This is +/// a slightly hacky way to implement the overloading rules for elidable copy +/// initialization in C++0x (C++0x 12.8p15). void Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions) + bool SuppressUserConversions, bool ForceRValue) { const FunctionProtoType* Proto = dyn_cast<FunctionProtoType>(Method->getType()->getAsFunctionType()); @@ -2169,7 +2187,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object, QualType ParamType = Proto->getArgType(ArgIdx); Candidate.Conversions[ArgIdx + 1] = TryCopyInitialization(Args[ArgIdx], ParamType, - SuppressUserConversions); + SuppressUserConversions, ForceRValue); if (Candidate.Conversions[ArgIdx + 1].ConversionKind == ImplicitConversionSequence::BadConversion) { Candidate.Viable = false; |