summaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaTemplateVariadic.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /clang/lib/Sema/SemaTemplateVariadic.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'clang/lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp63
1 files changed, 53 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 7b77d1cb482a..1951aec3d17d 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -368,8 +368,8 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
Locations.push_back(Unexpanded[I].second);
}
- DiagnosticBuilder DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
- << (int)UPPC << (int)Names.size();
+ auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
+ << (int)UPPC << (int)Names.size();
for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
DB << Names[I];
@@ -408,6 +408,29 @@ bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
}
+bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
+ if (!RE->containsUnexpandedParameterPack())
+ return false;
+
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
+ assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
+
+ // We only care about unexpanded references to the RequiresExpr's own
+ // parameter packs.
+ auto Parms = RE->getLocalParameters();
+ llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
+ SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
+ for (auto Parm : Unexpanded)
+ if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl*>()))
+ UnexpandedParms.push_back(Parm);
+ if (UnexpandedParms.empty())
+ return false;
+
+ return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement,
+ UnexpandedParms);
+}
+
bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
UnexpandedParameterPackContext UPPC) {
// C++0x [temp.variadic]p5:
@@ -614,7 +637,8 @@ QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
return QualType();
}
- return Context.getPackExpansionType(Pattern, NumExpansions);
+ return Context.getPackExpansionType(Pattern, NumExpansions,
+ /*ExpectPackInType=*/false);
}
ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
@@ -1071,7 +1095,7 @@ Sema::getTemplateArgumentPackExpansionPattern(
case TemplateArgument::TemplateExpansion:
Ellipsis = OrigLoc.getTemplateEllipsisLoc();
NumExpansions = Argument.getNumTemplateExpansions();
- return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
+ return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(),
OrigLoc.getTemplateQualifierLoc(),
OrigLoc.getTemplateNameLoc());
@@ -1159,7 +1183,7 @@ static void CheckFoldOperand(Sema &S, Expr *E) {
}
}
-ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
+ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
tok::TokenKind Operator,
SourceLocation EllipsisLoc, Expr *RHS,
SourceLocation RParenLoc) {
@@ -1201,18 +1225,37 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
}
BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
- return BuildCXXFoldExpr(LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
+
+ // Perform first-phase name lookup now.
+ UnresolvedLookupExpr *ULE = nullptr;
+ {
+ UnresolvedSet<16> Functions;
+ LookupBinOp(S, EllipsisLoc, Opc, Functions);
+ if (!Functions.empty()) {
+ DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(
+ BinaryOperator::getOverloadedOperator(Opc));
+ ExprResult Callee = CreateUnresolvedLookupExpr(
+ /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
+ DeclarationNameInfo(OpName, EllipsisLoc), Functions);
+ if (Callee.isInvalid())
+ return ExprError();
+ ULE = cast<UnresolvedLookupExpr>(Callee.get());
+ }
+ }
+
+ return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
None);
}
-ExprResult Sema::BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
+ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee,
+ SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Operator,
SourceLocation EllipsisLoc, Expr *RHS,
SourceLocation RParenLoc,
Optional<unsigned> NumExpansions) {
- return new (Context) CXXFoldExpr(Context.DependentTy, LParenLoc, LHS,
- Operator, EllipsisLoc, RHS, RParenLoc,
- NumExpansions);
+ return new (Context)
+ CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator,
+ EllipsisLoc, RHS, RParenLoc, NumExpansions);
}
ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,