diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
| -rw-r--r-- | lib/Sema/SemaOverload.cpp | 56 | 
1 files changed, 52 insertions, 4 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 1caa94c9a4588..e0c10e4479e25 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -543,6 +543,12 @@ namespace {    struct DFIParamWithArguments : DFIArguments {      TemplateParameter Param;    }; +  // Structure used by DeductionFailureInfo to store template argument +  // information and the index of the problematic call argument. +  struct DFIDeducedMismatchArgs : DFIArguments { +    TemplateArgumentList *TemplateArgs; +    unsigned CallArgIndex; +  };  }  /// \brief Convert from Sema's representation of template deduction information @@ -554,13 +560,14 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,    DeductionFailureInfo Result;    Result.Result = static_cast<unsigned>(TDK);    Result.HasDiagnostic = false; -  Result.Data = nullptr;    switch (TDK) {    case Sema::TDK_Success:    case Sema::TDK_Invalid:    case Sema::TDK_InstantiationDepth:    case Sema::TDK_TooManyArguments:    case Sema::TDK_TooFewArguments: +  case Sema::TDK_MiscellaneousDeductionFailure: +    Result.Data = nullptr;      break;    case Sema::TDK_Incomplete: @@ -568,6 +575,17 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,      Result.Data = Info.Param.getOpaqueValue();      break; +  case Sema::TDK_DeducedMismatch: { +    // FIXME: Should allocate from normal heap so that we can free this later. +    auto *Saved = new (Context) DFIDeducedMismatchArgs; +    Saved->FirstArg = Info.FirstArg; +    Saved->SecondArg = Info.SecondArg; +    Saved->TemplateArgs = Info.take(); +    Saved->CallArgIndex = Info.CallArgIndex; +    Result.Data = Saved; +    break; +  } +    case Sema::TDK_NonDeducedMismatch: {      // FIXME: Should allocate from normal heap so that we can free this later.      DFIArguments *Saved = new (Context) DFIArguments; @@ -601,9 +619,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,    case Sema::TDK_FailedOverloadResolution:      Result.Data = Info.Expression;      break; - -  case Sema::TDK_MiscellaneousDeductionFailure: -    break;    }    return Result; @@ -623,6 +638,7 @@ void DeductionFailureInfo::Destroy() {    case Sema::TDK_Inconsistent:    case Sema::TDK_Underqualified: +  case Sema::TDK_DeducedMismatch:    case Sema::TDK_NonDeducedMismatch:      // FIXME: Destroy the data?      Data = nullptr; @@ -657,6 +673,7 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {    case Sema::TDK_TooManyArguments:    case Sema::TDK_TooFewArguments:    case Sema::TDK_SubstitutionFailure: +  case Sema::TDK_DeducedMismatch:    case Sema::TDK_NonDeducedMismatch:    case Sema::TDK_FailedOverloadResolution:      return TemplateParameter(); @@ -692,6 +709,9 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {    case Sema::TDK_FailedOverloadResolution:      return nullptr; +  case Sema::TDK_DeducedMismatch: +    return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs; +    case Sema::TDK_SubstitutionFailure:      return static_cast<TemplateArgumentList*>(Data); @@ -718,6 +738,7 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() {    case Sema::TDK_Inconsistent:    case Sema::TDK_Underqualified: +  case Sema::TDK_DeducedMismatch:    case Sema::TDK_NonDeducedMismatch:      return &static_cast<DFIArguments*>(Data)->FirstArg; @@ -744,6 +765,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {    case Sema::TDK_Inconsistent:    case Sema::TDK_Underqualified: +  case Sema::TDK_DeducedMismatch:    case Sema::TDK_NonDeducedMismatch:      return &static_cast<DFIArguments*>(Data)->SecondArg; @@ -763,6 +785,14 @@ Expr *DeductionFailureInfo::getExpr() {    return nullptr;  } +llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() { +  if (static_cast<Sema::TemplateDeductionResult>(Result) == +        Sema::TDK_DeducedMismatch) +    return static_cast<DFIDeducedMismatchArgs*>(Data)->CallArgIndex; + +  return llvm::None; +} +  void OverloadCandidateSet::destroyCandidates() {    for (iterator i = begin(), e = end(); i != e; ++i) {      for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii) @@ -9397,6 +9427,23 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated,      return;    } +  case Sema::TDK_DeducedMismatch: { +    // Format the template argument list into the argument string. +    SmallString<128> TemplateArgString; +    if (TemplateArgumentList *Args = +            DeductionFailure.getTemplateArgumentList()) { +      TemplateArgString = " "; +      TemplateArgString += S.getTemplateArgumentBindingsText( +          getDescribedTemplate(Templated)->getTemplateParameters(), *Args); +    } + +    S.Diag(Templated->getLocation(), diag::note_ovl_candidate_deduced_mismatch) +        << (*DeductionFailure.getCallArgIndex() + 1) +        << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg() +        << TemplateArgString; +    break; +  } +    case Sema::TDK_NonDeducedMismatch: {      // FIXME: Provide a source location to indicate what we couldn't match.      TemplateArgument FirstTA = *DeductionFailure.getFirstArg(); @@ -9686,6 +9733,7 @@ static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) {      return 2;    case Sema::TDK_SubstitutionFailure: +  case Sema::TDK_DeducedMismatch:    case Sema::TDK_NonDeducedMismatch:    case Sema::TDK_MiscellaneousDeductionFailure:      return 3;  | 
