diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
| -rw-r--r-- | lib/Sema/SemaOverload.cpp | 177 | 
1 files changed, 109 insertions, 68 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index f976b76727f5..29ba34479dab 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -131,7 +131,7 @@ ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) {      ICR_Conversion,      ICR_Conversion,      ICR_Conversion, -    ICR_Conversion, +    ICR_OCL_Scalar_Widening,      ICR_Complex_Real_Conversion,      ICR_Conversion,      ICR_Conversion, @@ -917,40 +917,39 @@ static bool checkArgPlaceholdersForOverload(Sema &S,    return false;  } -// IsOverload - Determine whether the given New declaration is an -// overload of the declarations in Old. This routine returns false if -// New and Old cannot be overloaded, e.g., if New has the same -// signature as some function in Old (C++ 1.3.10) or if the Old -// declarations aren't functions (or function templates) at all. When -// it does return false, MatchedDecl will point to the decl that New -// cannot be overloaded with.  This decl may be a UsingShadowDecl on -// top of the underlying declaration. -// -// Example: Given the following input: -// -//   void f(int, float); // #1 -//   void f(int, int); // #2 -//   int f(int, int); // #3 -// -// When we process #1, there is no previous declaration of "f", -// so IsOverload will not be used. -// -// When we process #2, Old contains only the FunctionDecl for #1.  By -// comparing the parameter types, we see that #1 and #2 are overloaded -// (since they have different signatures), so this routine returns -// false; MatchedDecl is unchanged. -// -// When we process #3, Old is an overload set containing #1 and #2. We -// compare the signatures of #3 to #1 (they're overloaded, so we do -// nothing) and then #3 to #2. Since the signatures of #3 and #2 are -// identical (return types of functions are not part of the -// signature), IsOverload returns false and MatchedDecl will be set to -// point to the FunctionDecl for #2. -// -// 'NewIsUsingShadowDecl' indicates that 'New' is being introduced -// into a class by a using declaration.  The rules for whether to hide -// shadow declarations ignore some properties which otherwise figure -// into a function template's signature. +/// Determine whether the given New declaration is an overload of the +/// declarations in Old. This routine returns Ovl_Match or Ovl_NonFunction if +/// New and Old cannot be overloaded, e.g., if New has the same signature as +/// some function in Old (C++ 1.3.10) or if the Old declarations aren't +/// functions (or function templates) at all. When it does return Ovl_Match or +/// Ovl_NonFunction, MatchedDecl will point to the decl that New cannot be +/// overloaded with. This decl may be a UsingShadowDecl on top of the underlying +/// declaration. +/// +/// Example: Given the following input: +/// +///   void f(int, float); // #1 +///   void f(int, int); // #2 +///   int f(int, int); // #3 +/// +/// When we process #1, there is no previous declaration of "f", so IsOverload +/// will not be used. +/// +/// When we process #2, Old contains only the FunctionDecl for #1. By comparing +/// the parameter types, we see that #1 and #2 are overloaded (since they have +/// different signatures), so this routine returns Ovl_Overload; MatchedDecl is +/// unchanged. +/// +/// When we process #3, Old is an overload set containing #1 and #2. We compare +/// the signatures of #3 to #1 (they're overloaded, so we do nothing) and then +/// #3 to #2. Since the signatures of #3 and #2 are identical (return types of +/// functions are not part of the signature), IsOverload returns Ovl_Match and +/// MatchedDecl will be set to point to the FunctionDecl for #2. +/// +/// 'NewIsUsingShadowDecl' indicates that 'New' is being introduced into a class +/// by a using declaration. The rules for whether to hide shadow declarations +/// ignore some properties which otherwise figure into a function template's +/// signature.  Sema::OverloadKind  Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,                      NamedDecl *&Match, bool NewIsUsingDecl) { @@ -4048,7 +4047,7 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,          = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2);        bool ToAssignRight          = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1); -       +        // A conversion to an a non-id object pointer type or qualified 'id'         // type is better than a conversion to 'id'.        if (ToPtr1->isObjCIdType() && @@ -4082,11 +4081,25 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,          return ImplicitConversionSequence::Better;        //   -- "conversion of C* to B* is better than conversion of C* to A*," -      if (S.Context.hasSameType(FromType1, FromType2) &&  +      if (S.Context.hasSameType(FromType1, FromType2) &&            !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() && -          (ToAssignLeft != ToAssignRight)) +          (ToAssignLeft != ToAssignRight)) { +        if (FromPtr1->isSpecialized()) { +          // "conversion of B<A> * to B * is better than conversion of B * to +          // C *. +          bool IsFirstSame = +              FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl(); +          bool IsSecondSame = +              FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl(); +          if (IsFirstSame) { +            if (!IsSecondSame) +              return ImplicitConversionSequence::Better; +          } else if (IsSecondSame) +            return ImplicitConversionSequence::Worse; +        }          return ToAssignLeft? ImplicitConversionSequence::Worse                             : ImplicitConversionSequence::Better; +      }        //   -- "conversion of B* to A* is better than conversion of C* to A*,"        if (S.Context.hasSameUnqualifiedType(ToType1, ToType2) && @@ -4264,7 +4277,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,      return Ref_Related;  } -/// \brief Look for a user-defined conversion to an value reference-compatible +/// \brief Look for a user-defined conversion to a value reference-compatible  ///        with DeclType. Return true if something definite is found.  static bool  FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, @@ -5888,7 +5901,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,      return;    // Overload resolution is always an unevaluated context. -  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); +  EnterExpressionEvaluationContext Unevaluated( +      *this, Sema::ExpressionEvaluationContext::Unevaluated);    // Add this candidate    OverloadCandidate &Candidate = @@ -6307,30 +6321,45 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,    for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {      NamedDecl *D = F.getDecl()->getUnderlyingDecl();      if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { -      if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) +      if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) { +        QualType ObjectType; +        Expr::Classification ObjectClassification; +        if (Expr *E = Args[0]) { +          // Use the explit base to restrict the lookup: +          ObjectType = E->getType(); +          ObjectClassification = E->Classify(Context); +        } // .. else there is an implit base.          AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), -                           cast<CXXMethodDecl>(FD)->getParent(), -                           Args[0]->getType(), Args[0]->Classify(Context), -                           Args.slice(1), CandidateSet, SuppressUserConversions, -                           PartialOverloading); -      else +                           cast<CXXMethodDecl>(FD)->getParent(), ObjectType, +                           ObjectClassification, Args.slice(1), CandidateSet, +                           SuppressUserConversions, PartialOverloading); +      } else {          AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet,                               SuppressUserConversions, PartialOverloading); +      }      } else {        FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D);        if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) && -          !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) +          !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) { +        QualType ObjectType; +        Expr::Classification ObjectClassification; +        if (Expr *E = Args[0]) { +          // Use the explit base to restrict the lookup: +          ObjectType = E->getType(); +          ObjectClassification = E->Classify(Context); +        } // .. else there is an implit base.          AddMethodTemplateCandidate(              FunTmpl, F.getPair(),              cast<CXXRecordDecl>(FunTmpl->getDeclContext()), -            ExplicitTemplateArgs, Args[0]->getType(), -            Args[0]->Classify(Context), Args.slice(1), CandidateSet, -            SuppressUserConversions, PartialOverloading); -      else +            ExplicitTemplateArgs, ObjectType, ObjectClassification, +            Args.slice(1), CandidateSet, SuppressUserConversions, +            PartialOverloading); +      } else {          AddTemplateOverloadCandidate(FunTmpl, F.getPair(),                                       ExplicitTemplateArgs, Args,                                       CandidateSet, SuppressUserConversions,                                       PartialOverloading); +      }      }    }  } @@ -6396,7 +6425,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,      return;    // Overload resolution is always an unevaluated context. -  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); +  EnterExpressionEvaluationContext Unevaluated( +      *this, Sema::ExpressionEvaluationContext::Unevaluated);    // Add this candidate    OverloadCandidate &Candidate = @@ -6652,7 +6682,8 @@ bool Sema::CheckNonDependentConversions(        CandidateSet.allocateConversionSequences(ThisConversions + Args.size());    // Overload resolution is always an unevaluated context. -  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); +  EnterExpressionEvaluationContext Unevaluated( +      *this, Sema::ExpressionEvaluationContext::Unevaluated);    // For a method call, check the 'this' conversion here too. DR1391 doesn't    // require that, but this check should never result in a hard error, and @@ -6760,7 +6791,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,      return;    // Overload resolution is always an unevaluated context. -  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); +  EnterExpressionEvaluationContext Unevaluated( +      *this, Sema::ExpressionEvaluationContext::Unevaluated);    // Add this candidate    OverloadCandidate &Candidate = CandidateSet.addCandidate(1); @@ -6951,7 +6983,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,      return;    // Overload resolution is always an unevaluated context. -  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); +  EnterExpressionEvaluationContext Unevaluated( +      *this, Sema::ExpressionEvaluationContext::Unevaluated);    OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1);    Candidate.FoundDecl = FoundDecl; @@ -7109,7 +7142,8 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,                                 bool IsAssignmentOperator,                                 unsigned NumContextualBoolArguments) {    // Overload resolution is always an unevaluated context. -  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); +  EnterExpressionEvaluationContext Unevaluated( +      *this, Sema::ExpressionEvaluationContext::Unevaluated);    // Add this candidate    OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); @@ -8991,6 +9025,12 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1,      // C++14 [over.match.best]p1 section 2 bullet 3.    } +  //    -- F1 is generated from a deduction-guide and F2 is not +  auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function); +  auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function); +  if (Guide1 && Guide2 && Guide1->isImplicit() != Guide2->isImplicit()) +    return Guide2->isImplicit(); +    //    -- F1 is a non-template function and F2 is a function template    //       specialization, or, if not that,    bool Cand1IsSpecialization = Cand1.Function && @@ -9488,7 +9528,8 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,          << (unsigned) FnKind << FnDesc          << (FromExpr ? FromExpr->getSourceRange() : SourceRange())          << FromTy -        << FromQs.getAddressSpace() << ToQs.getAddressSpace() +        << FromQs.getAddressSpaceAttributePrintValue() +        << ToQs.getAddressSpaceAttributePrintValue()          << (unsigned) isObjectArgument << I+1;        MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);        return; @@ -11485,7 +11526,7 @@ DiagnoseTwoPhaseLookup(Sema &SemaRef, SourceLocation FnLoc,                         TemplateArgumentListInfo *ExplicitTemplateArgs,                         ArrayRef<Expr *> Args,                         bool *DoDiagnoseEmptyLookup = nullptr) { -  if (SemaRef.ActiveTemplateInstantiations.empty() || !SS.isEmpty()) +  if (!SemaRef.inTemplateInstantiation() || !SS.isEmpty())      return false;    for (DeclContext *DC = SemaRef.CurContext; DC; DC = DC->getParent()) { @@ -11957,7 +11998,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,                                       Fns.begin(), Fns.end());      return new (Context)          CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy, -                            VK_RValue, OpLoc, false); +                            VK_RValue, OpLoc, FPOptions());    }    // Build an empty overload set. @@ -12027,7 +12068,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,        Args[0] = Input;        CallExpr *TheCall =          new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray, -                                          ResultTy, VK, OpLoc, false); +                                          ResultTy, VK, OpLoc, FPOptions());        if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))          return ExprError(); @@ -12125,12 +12166,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,        if (Opc <= BO_Assign || Opc > BO_OrAssign)          return new (Context) BinaryOperator(              Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary, -            OpLoc, FPFeatures.fp_contract); +            OpLoc, FPFeatures);        return new (Context) CompoundAssignOperator(            Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,            Context.DependentTy, Context.DependentTy, OpLoc, -          FPFeatures.fp_contract); +          FPFeatures);      }      // FIXME: save results of ADL from here? @@ -12144,7 +12185,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,                                       Fns.begin(), Fns.end());      return new (Context)          CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy, -                            VK_RValue, OpLoc, FPFeatures.fp_contract); +                            VK_RValue, OpLoc, FPFeatures);    }    // Always do placeholder-like conversions on the RHS. @@ -12259,7 +12300,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,          CXXOperatorCallExpr *TheCall =            new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(),                                              Args, ResultTy, VK, OpLoc, -                                            FPFeatures.fp_contract); +                                            FPFeatures);          if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall,                                  FnDecl)) @@ -12407,7 +12448,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,      return new (Context)          CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args, -                            Context.DependentTy, VK_RValue, RLoc, false); +                            Context.DependentTy, VK_RValue, RLoc, FPOptions());    }    // Handle placeholders on both operands. @@ -12483,7 +12524,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,            new (Context) CXXOperatorCallExpr(Context, OO_Subscript,                                              FnExpr.get(), Args,                                              ResultTy, VK, RLoc, -                                            false); +                                            FPOptions());          if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))            return ExprError(); @@ -13046,7 +13087,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,    CXXOperatorCallExpr *TheCall = new (Context)        CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, -                          VK, RParenLoc, false); +                          VK, RParenLoc, FPOptions());    if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method))      return true; @@ -13226,7 +13267,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,    ResultTy = ResultTy.getNonLValueExprType(Context);    CXXOperatorCallExpr *TheCall =      new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(), -                                      Base, ResultTy, VK, OpLoc, false); +                                      Base, ResultTy, VK, OpLoc, FPOptions());    if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))      return ExprError();  | 
