From e3b557809604d036af6e00c60f012c2025b59a5e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 11 Feb 2023 13:38:04 +0100 Subject: Vendor import of llvm-project main llvmorg-16-init-18548-gb0daacf58f41, the last commit before the upstream release/17.x branch was created. --- clang/lib/Sema/SemaTemplateVariadic.cpp | 286 +++++++++++++++++--------------- 1 file changed, 148 insertions(+), 138 deletions(-) (limited to 'clang/lib/Sema/SemaTemplateVariadic.cpp') diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 790792f77b24..01a435668d88 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -18,6 +18,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" +#include using namespace clang; @@ -88,6 +89,23 @@ namespace { return true; } + bool + VisitSubstTemplateTypeParmPackTypeLoc(SubstTemplateTypeParmPackTypeLoc TL) { + Unexpanded.push_back({TL.getTypePtr(), TL.getNameLoc()}); + return true; + } + + bool VisitSubstTemplateTypeParmPackType(SubstTemplateTypeParmPackType *T) { + Unexpanded.push_back({T, SourceLocation()}); + return true; + } + + bool + VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr *E) { + Unexpanded.push_back({E, E->getParameterPackLocation()}); + return true; + } + /// Record occurrences of function and non-type template /// parameter packs in an expression. bool VisitDeclRefExpr(DeclRefExpr *E) { @@ -306,7 +324,8 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, auto *TTPD = dyn_cast(LocalPack); return TTPD && TTPD->getTypeForDecl() == TTPT; } - return declaresSameEntity(Pack.first.get(), LocalPack); + return declaresSameEntity(Pack.first.get(), + LocalPack); }; if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack)) LambdaParamPackReferences.push_back(Pack); @@ -358,7 +377,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, = Unexpanded[I].first.dyn_cast()) Name = TTP->getIdentifier(); else - Name = Unexpanded[I].first.get()->getIdentifier(); + Name = Unexpanded[I].first.get()->getIdentifier(); if (Name && NamesKnown.insert(Name).second) Names.push_back(Name); @@ -421,7 +440,7 @@ bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) { llvm::SmallPtrSet ParmSet(Parms.begin(), Parms.end()); SmallVector UnexpandedParms; for (auto Parm : Unexpanded) - if (ParmSet.contains(Parm.first.dyn_cast())) + if (ParmSet.contains(Parm.first.dyn_cast())) UnexpandedParms.push_back(Parm); if (UnexpandedParms.empty()) return false; @@ -594,7 +613,8 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type, if (!TSInfo) return true; - TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None); + TypeSourceInfo *TSResult = + CheckPackExpansion(TSInfo, EllipsisLoc, std::nullopt); if (!TSResult) return true; @@ -603,7 +623,7 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type, TypeSourceInfo * Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, - Optional NumExpansions) { + std::optional NumExpansions) { // Create the pack expansion type and source-location information. QualType Result = CheckPackExpansion(Pattern->getType(), Pattern->getTypeLoc().getSourceRange(), @@ -621,7 +641,7 @@ Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, SourceLocation EllipsisLoc, - Optional NumExpansions) { + std::optional NumExpansions) { // C++11 [temp.variadic]p5: // The pattern of a pack expansion shall name one or more // parameter packs that are not expanded by a nested pack @@ -641,11 +661,11 @@ QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, } ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { - return CheckPackExpansion(Pattern, EllipsisLoc, None); + return CheckPackExpansion(Pattern, EllipsisLoc, std::nullopt); } ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, - Optional NumExpansions) { + std::optional NumExpansions) { if (!Pattern) return ExprError(); @@ -669,112 +689,98 @@ bool Sema::CheckParameterPacksForExpansion( SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, - bool &RetainExpansion, Optional &NumExpansions) { + bool &RetainExpansion, std::optional &NumExpansions) { ShouldExpand = true; RetainExpansion = false; - std::pair FirstPack; - bool HaveFirstPack = false; - Optional NumPartialExpansions; - SourceLocation PartiallySubstitutedPackLoc; + std::pair FirstPack; + std::optional> PartialExpansion; + std::optional CurNumExpansions; - for (UnexpandedParameterPack ParmPack : Unexpanded) { + for (auto [P, Loc] : Unexpanded) { // Compute the depth and index for this parameter pack. - unsigned Depth = 0, Index = 0; - IdentifierInfo *Name; - bool IsVarDeclPack = false; - - if (const TemplateTypeParmType *TTP = - ParmPack.first.dyn_cast()) { - Depth = TTP->getDepth(); - Index = TTP->getIndex(); - Name = TTP->getIdentifier(); - } else { - NamedDecl *ND = ParmPack.first.get(); - if (isa(ND)) - IsVarDeclPack = true; - else - std::tie(Depth, Index) = getDepthAndIndex(ND); - - Name = ND->getIdentifier(); - } - - // Determine the size of this argument pack. + std::optional> Pos; unsigned NewPackSize; - if (IsVarDeclPack) { - // Figure out whether we're instantiating to an argument pack or not. - typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; - - llvm::PointerUnion *Instantiation = - CurrentInstantiationScope->findInstantiationOf( - ParmPack.first.get()); - if (Instantiation->is()) { - // We could expand this function parameter pack. - NewPackSize = Instantiation->get()->size(); - } else { + const auto *ND = P.dyn_cast(); + if (ND && isa(ND)) { + const auto *DAP = + CurrentInstantiationScope->findInstantiationOf(ND) + ->dyn_cast(); + if (!DAP) { // We can't expand this function parameter pack, so we can't expand // the pack expansion. ShouldExpand = false; continue; } + NewPackSize = DAP->size(); + } else if (ND) { + Pos = getDepthAndIndex(ND); + } else if (const auto *TTP = P.dyn_cast()) { + Pos = {TTP->getDepth(), TTP->getIndex()}; + ND = TTP->getDecl(); + // FIXME: We either should have some fallback for canonical TTP, or + // never have canonical TTP here. + } else if (const auto *STP = + P.dyn_cast()) { + NewPackSize = STP->getNumArgs(); + ND = STP->getReplacedParameter(); } else { + const auto *SEP = P.get(); + NewPackSize = SEP->getArgumentPack().pack_size(); + ND = SEP->getParameterPack(); + } + + if (Pos) { // If we don't have a template argument at this depth/index, then we // cannot expand the pack expansion. Make a note of this, but we still // want to check any parameter packs we *do* have arguments for. - if (Depth >= TemplateArgs.getNumLevels() || - !TemplateArgs.hasTemplateArgument(Depth, Index)) { + if (Pos->first >= TemplateArgs.getNumLevels() || + !TemplateArgs.hasTemplateArgument(Pos->first, Pos->second)) { ShouldExpand = false; continue; } - // Determine the size of the argument pack. - NewPackSize = TemplateArgs(Depth, Index).pack_size(); - } - - // C++0x [temp.arg.explicit]p9: - // Template argument deduction can extend the sequence of template - // arguments corresponding to a template parameter pack, even when the - // sequence contains explicitly specified template arguments. - if (!IsVarDeclPack && CurrentInstantiationScope) { - if (NamedDecl *PartialPack - = CurrentInstantiationScope->getPartiallySubstitutedPack()){ - unsigned PartialDepth, PartialIndex; - std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack); - if (PartialDepth == Depth && PartialIndex == Index) { + NewPackSize = TemplateArgs(Pos->first, Pos->second).pack_size(); + // C++0x [temp.arg.explicit]p9: + // Template argument deduction can extend the sequence of template + // arguments corresponding to a template parameter pack, even when the + // sequence contains explicitly specified template arguments. + if (CurrentInstantiationScope) + if (const NamedDecl *PartialPack = + CurrentInstantiationScope->getPartiallySubstitutedPack(); + PartialPack && getDepthAndIndex(PartialPack) == *Pos) { RetainExpansion = true; // We don't actually know the new pack size yet. - NumPartialExpansions = NewPackSize; - PartiallySubstitutedPackLoc = ParmPack.second; + PartialExpansion = {NewPackSize, Loc}; continue; } - } } - if (!NumExpansions) { + // FIXME: Workaround for Canonical TTP. + const IdentifierInfo *Name = ND ? ND->getIdentifier() : nullptr; + if (!CurNumExpansions) { // The is the first pack we've seen for which we have an argument. // Record it. - NumExpansions = NewPackSize; - FirstPack.first = Name; - FirstPack.second = ParmPack.second; - HaveFirstPack = true; - continue; - } - - if (NewPackSize != *NumExpansions) { + CurNumExpansions = NewPackSize; + FirstPack = {Name, Loc}; + } else if (NewPackSize != *CurNumExpansions) { // C++0x [temp.variadic]p5: // All of the parameter packs expanded by a pack expansion shall have // the same number of arguments specified. - if (HaveFirstPack) - Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) - << FirstPack.first << Name << *NumExpansions << NewPackSize - << SourceRange(FirstPack.second) << SourceRange(ParmPack.second); - else - Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) - << Name << *NumExpansions << NewPackSize - << SourceRange(ParmPack.second); + Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) + << FirstPack.first << Name << *CurNumExpansions << NewPackSize + << SourceRange(FirstPack.second) << SourceRange(Loc); return true; } } + if (NumExpansions && CurNumExpansions && + *NumExpansions != *CurNumExpansions) { + Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) + << FirstPack.first << *CurNumExpansions << *NumExpansions + << SourceRange(FirstPack.second); + return true; + } + // If we're performing a partial expansion but we also have a full expansion, // expand to the number of common arguments. For example, given: // @@ -784,70 +790,72 @@ bool Sema::CheckParameterPacksForExpansion( // // ... a call to 'A().f' should expand the pack once and // retain an expansion. - if (NumPartialExpansions) { - if (NumExpansions && *NumExpansions < *NumPartialExpansions) { + if (PartialExpansion) { + if (CurNumExpansions && *CurNumExpansions < PartialExpansion->first) { NamedDecl *PartialPack = CurrentInstantiationScope->getPartiallySubstitutedPack(); Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial) - << PartialPack << *NumPartialExpansions << *NumExpansions - << SourceRange(PartiallySubstitutedPackLoc); + << PartialPack << PartialExpansion->first << *CurNumExpansions + << SourceRange(PartialExpansion->second); return true; } - - NumExpansions = NumPartialExpansions; + NumExpansions = PartialExpansion->first; + } else { + NumExpansions = CurNumExpansions; } return false; } -Optional Sema::getNumArgumentsInExpansion(QualType T, - const MultiLevelTemplateArgumentList &TemplateArgs) { +std::optional Sema::getNumArgumentsInExpansion( + QualType T, const MultiLevelTemplateArgumentList &TemplateArgs) { QualType Pattern = cast(T)->getPattern(); SmallVector Unexpanded; CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); - Optional Result; - for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { - // Compute the depth and index for this parameter pack. - unsigned Depth; - unsigned Index; + std::optional Result; + auto setResultSz = [&Result](unsigned Size) { + assert((!Result || *Result == Size) && "inconsistent pack sizes"); + Result = Size; + }; + auto setResultPos = [&](const std::pair &Pos) -> bool { + unsigned Depth = Pos.first, Index = Pos.second; + if (Depth >= TemplateArgs.getNumLevels() || + !TemplateArgs.hasTemplateArgument(Depth, Index)) + // The pattern refers to an unknown template argument. We're not ready to + // expand this pack yet. + return true; + // Determine the size of the argument pack. + setResultSz(TemplateArgs(Depth, Index).pack_size()); + return false; + }; - if (const TemplateTypeParmType *TTP - = Unexpanded[I].first.dyn_cast()) { - Depth = TTP->getDepth(); - Index = TTP->getIndex(); + for (auto [I, _] : Unexpanded) { + if (const auto *TTP = I.dyn_cast()) { + if (setResultPos({TTP->getDepth(), TTP->getIndex()})) + return std::nullopt; + } else if (const auto *STP = + I.dyn_cast()) { + setResultSz(STP->getNumArgs()); + } else if (const auto *SEP = + I.dyn_cast()) { + setResultSz(SEP->getArgumentPack().pack_size()); } else { - NamedDecl *ND = Unexpanded[I].first.get(); + const auto *ND = I.get(); + // Function parameter pack or init-capture pack. if (isa(ND)) { - // Function parameter pack or init-capture pack. - typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; - - llvm::PointerUnion *Instantiation - = CurrentInstantiationScope->findInstantiationOf( - Unexpanded[I].first.get()); - if (Instantiation->is()) + const auto *DAP = + CurrentInstantiationScope->findInstantiationOf(ND) + ->dyn_cast(); + if (!DAP) // The pattern refers to an unexpanded pack. We're not ready to expand // this pack yet. - return None; - - unsigned Size = Instantiation->get()->size(); - assert((!Result || *Result == Size) && "inconsistent pack sizes"); - Result = Size; - continue; + return std::nullopt; + setResultSz(DAP->size()); + } else if (setResultPos(getDepthAndIndex(ND))) { + return std::nullopt; } - - std::tie(Depth, Index) = getDepthAndIndex(ND); } - if (Depth >= TemplateArgs.getNumLevels() || - !TemplateArgs.hasTemplateArgument(Depth, Index)) - // The pattern refers to an unknown template argument. We're not ready to - // expand this pack yet. - return None; - - // Determine the size of the argument pack. - unsigned Size = TemplateArgs(Depth, Index).pack_size(); - assert((!Result || *Result == Size) && "inconsistent pack sizes"); - Result = Size; } return Result; @@ -857,8 +865,10 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { const DeclSpec &DS = D.getDeclSpec(); switch (DS.getTypeSpecType()) { case TST_typename: + case TST_typeof_unqualType: case TST_typeofType: - case TST_underlyingType: +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: +#include "clang/Basic/TransformTypeTraits.def" case TST_atomic: { QualType T = DS.getRepAsType().get(); if (!T.isNull() && T->containsUnexpandedParameterPack()) @@ -866,6 +876,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { break; } + case TST_typeof_unqualExpr: case TST_typeofExpr: case TST_decltype: case TST_bitint: @@ -1049,10 +1060,9 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, RParenLoc); } -TemplateArgumentLoc -Sema::getTemplateArgumentPackExpansionPattern( - TemplateArgumentLoc OrigLoc, - SourceLocation &Ellipsis, Optional &NumExpansions) const { +TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern( + TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis, + std::optional &NumExpansions) const { const TemplateArgument &Argument = OrigLoc.getArgument(); assert(Argument.isPackExpansion()); switch (Argument.getKind()) { @@ -1109,7 +1119,7 @@ Sema::getTemplateArgumentPackExpansionPattern( llvm_unreachable("Invalid TemplateArgument Kind!"); } -Optional Sema::getFullyPackExpandedSize(TemplateArgument Arg) { +std::optional Sema::getFullyPackExpandedSize(TemplateArgument Arg) { assert(Arg.containsUnexpandedParameterPack()); // If this is a substituted pack, grab that pack. If not, we don't know @@ -1123,7 +1133,7 @@ Optional Sema::getFullyPackExpandedSize(TemplateArgument Arg) { if (auto *Subst = Arg.getAsType()->getAs()) Pack = Subst->getArgumentPack(); else - return None; + return std::nullopt; break; case TemplateArgument::Expression: @@ -1133,10 +1143,10 @@ Optional Sema::getFullyPackExpandedSize(TemplateArgument Arg) { else if (auto *Subst = dyn_cast(Arg.getAsExpr())) { for (VarDecl *PD : *Subst) if (PD->isParameterPack()) - return None; + return std::nullopt; return Subst->getNumExpansions(); } else - return None; + return std::nullopt; break; case TemplateArgument::Template: @@ -1144,7 +1154,7 @@ Optional Sema::getFullyPackExpandedSize(TemplateArgument Arg) { Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) Pack = Subst->getArgumentPack(); else - return None; + return std::nullopt; break; case TemplateArgument::Declaration: @@ -1153,7 +1163,7 @@ Optional Sema::getFullyPackExpandedSize(TemplateArgument Arg) { case TemplateArgument::Integral: case TemplateArgument::Pack: case TemplateArgument::Null: - return None; + return std::nullopt; } // Check that no argument in the pack is itself a pack expansion. @@ -1161,7 +1171,7 @@ Optional Sema::getFullyPackExpandedSize(TemplateArgument Arg) { // There's no point recursing in this case; we would have already // expanded this pack expansion into the enclosing pack if we could. if (Elem.isPackExpansion()) - return None; + return std::nullopt; } return Pack.pack_size(); } @@ -1242,7 +1252,7 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, } return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc, - None); + std::nullopt); } ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, @@ -1250,7 +1260,7 @@ ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, - Optional NumExpansions) { + std::optional NumExpansions) { return new (Context) CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator, EllipsisLoc, RHS, RParenLoc, NumExpansions); -- cgit v1.2.3