summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2019-12-06 01:30:21 +0200
committerSaar Raz <saar@raz.email>2019-12-06 01:34:20 +0200
commitfdf80e86a52849813d05da4b6c25884c06ba9e98 (patch)
treef08ca57be85567d41a118bedb588a8152763c360 /clang/lib/Sema/SemaOverload.cpp
parent7faa8440440f280912c33a27c14c0dc4031532de (diff)
downloadbcm5719-llvm-fdf80e86a52849813d05da4b6c25884c06ba9e98.tar.gz
bcm5719-llvm-fdf80e86a52849813d05da4b6c25884c06ba9e98.zip
[Concepts] Constraint Enforcement & Diagnostics
Part of the C++20 concepts implementation effort. - Associated constraints (requires clauses, currently) are now enforced when instantiating/specializing templates and when considering partial specializations and function overloads. - Elaborated diagnostics give helpful insight as to why the constraints were not satisfied. Phabricator: D41569 Re-commit, after fixing some memory bugs.
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a97847461e3..d733563c98d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -591,6 +591,12 @@ namespace {
TemplateArgumentList *TemplateArgs;
unsigned CallArgIndex;
};
+ // Structure used by DeductionFailureInfo to store information about
+ // unsatisfied constraints.
+ struct CNSInfo {
+ TemplateArgumentList *TemplateArgs;
+ ConstraintSatisfaction Satisfaction;
+ };
}
/// Convert from Sema's representation of template deduction information
@@ -661,6 +667,14 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
}
break;
+ case Sema::TDK_ConstraintsNotSatisfied: {
+ CNSInfo *Saved = new (Context) CNSInfo;
+ Saved->TemplateArgs = Info.take();
+ Saved->Satisfaction = Info.AssociatedConstraintsSatisfaction;
+ Result.Data = Saved;
+ break;
+ }
+
case Sema::TDK_Success:
case Sema::TDK_NonDependentConversionFailure:
llvm_unreachable("not a deduction failure");
@@ -701,6 +715,15 @@ void DeductionFailureInfo::Destroy() {
}
break;
+ case Sema::TDK_ConstraintsNotSatisfied:
+ // FIXME: Destroy the template argument list?
+ Data = nullptr;
+ if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) {
+ Diag->~PartialDiagnosticAt();
+ HasDiagnostic = false;
+ }
+ break;
+
// Unhandled
case Sema::TDK_MiscellaneousDeductionFailure:
break;
@@ -726,6 +749,7 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() {
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_CUDATargetMismatch:
case Sema::TDK_NonDependentConversionFailure:
+ case Sema::TDK_ConstraintsNotSatisfied:
return TemplateParameter();
case Sema::TDK_Incomplete:
@@ -769,6 +793,9 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {
case Sema::TDK_SubstitutionFailure:
return static_cast<TemplateArgumentList*>(Data);
+ case Sema::TDK_ConstraintsNotSatisfied:
+ return static_cast<CNSInfo*>(Data)->TemplateArgs;
+
// Unhandled
case Sema::TDK_MiscellaneousDeductionFailure:
break;
@@ -789,6 +816,7 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() {
case Sema::TDK_SubstitutionFailure:
case Sema::TDK_CUDATargetMismatch:
case Sema::TDK_NonDependentConversionFailure:
+ case Sema::TDK_ConstraintsNotSatisfied:
return nullptr;
case Sema::TDK_IncompletePack:
@@ -820,6 +848,7 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() {
case Sema::TDK_SubstitutionFailure:
case Sema::TDK_CUDATargetMismatch:
case Sema::TDK_NonDependentConversionFailure:
+ case Sema::TDK_ConstraintsNotSatisfied:
return nullptr;
case Sema::TDK_Inconsistent:
@@ -1255,6 +1284,8 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
return NewTarget != OldTarget;
}
+ // TODO: Concepts: Check function trailing requires clauses here.
+
// The signatures match; this is not an overload.
return false;
}
@@ -10352,6 +10383,21 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
MaybeEmitInheritedConstructorNote(S, Found);
return;
+ case Sema::TDK_ConstraintsNotSatisfied: {
+ // Format the template argument list into the argument string.
+ SmallString<128> TemplateArgString;
+ TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList();
+ TemplateArgString = " ";
+ TemplateArgString += S.getTemplateArgumentBindingsText(
+ getDescribedTemplate(Templated)->getTemplateParameters(), *Args);
+ S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_unsatisfied_constraints)
+ << TemplateArgString;
+
+ S.DiagnoseUnsatisfiedConstraint(
+ static_cast<CNSInfo*>(DeductionFailure.Data)->Satisfaction);
+ return;
+ }
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
DiagnoseArityMismatch(S, Found, Templated, NumArgs);
@@ -10804,6 +10850,7 @@ static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) {
case Sema::TDK_SubstitutionFailure:
case Sema::TDK_DeducedMismatch:
+ case Sema::TDK_ConstraintsNotSatisfied:
case Sema::TDK_DeducedMismatchNested:
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_MiscellaneousDeductionFailure:
OpenPOWER on IntegriCloud