| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 1 | //===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/ | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 6 | //===----------------------------------------------------------------------===/ | 
|  | 7 | // | 
|  | 8 | //  This file implements semantic analysis for C++0x variadic templates. | 
|  | 9 | //===----------------------------------------------------------------------===/ | 
|  | 10 |  | 
|  | 11 | #include "clang/Sema/Sema.h" | 
| Chandler Carruth | 5553d0d | 2014-01-07 11:51:46 +0000 | [diff] [blame] | 12 | #include "TypeLocBuilder.h" | 
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 13 | #include "clang/AST/Expr.h" | 
|  | 14 | #include "clang/AST/RecursiveASTVisitor.h" | 
|  | 15 | #include "clang/AST/TypeLoc.h" | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 16 | #include "clang/Sema/Lookup.h" | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 17 | #include "clang/Sema/ParsedTemplate.h" | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 18 | #include "clang/Sema/ScopeInfo.h" | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 19 | #include "clang/Sema/SemaInternal.h" | 
| Douglas Gregor | 840bd6c | 2010-12-20 22:05:00 +0000 | [diff] [blame] | 20 | #include "clang/Sema/Template.h" | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 21 |  | 
|  | 22 | using namespace clang; | 
|  | 23 |  | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 24 | //---------------------------------------------------------------------------- | 
|  | 25 | // Visitor that collects unexpanded parameter packs | 
|  | 26 | //---------------------------------------------------------------------------- | 
|  | 27 |  | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 28 | namespace { | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 29 | /// A class that collects unexpanded parameter packs. | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 30 | class CollectUnexpandedParameterPacksVisitor : | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 31 | public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 32 | { | 
|  | 33 | typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> | 
|  | 34 | inherited; | 
|  | 35 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 36 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 37 |  | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 38 | bool InLambda = false; | 
|  | 39 | unsigned DepthLimit = (unsigned)-1; | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 40 |  | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 41 | void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) { | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 42 | if (auto *VD = dyn_cast<VarDecl>(ND)) { | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 43 | // For now, the only problematic case is a generic lambda's templated | 
|  | 44 | // call operator, so we don't need to look for all the other ways we | 
|  | 45 | // could have reached a dependent parameter pack. | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 46 | auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext()); | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 47 | auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr; | 
|  | 48 | if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit) | 
|  | 49 | return; | 
|  | 50 | } else if (getDepthAndIndex(ND).first >= DepthLimit) | 
|  | 51 | return; | 
|  | 52 |  | 
|  | 53 | Unexpanded.push_back({ND, Loc}); | 
|  | 54 | } | 
|  | 55 | void addUnexpanded(const TemplateTypeParmType *T, | 
|  | 56 | SourceLocation Loc = SourceLocation()) { | 
|  | 57 | if (T->getDepth() < DepthLimit) | 
|  | 58 | Unexpanded.push_back({T, Loc}); | 
|  | 59 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 60 |  | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 61 | public: | 
|  | 62 | explicit CollectUnexpandedParameterPacksVisitor( | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 63 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) | 
|  | 64 | : Unexpanded(Unexpanded) {} | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 65 |  | 
| Douglas Gregor | 15b4ec2 | 2010-12-20 23:07:20 +0000 | [diff] [blame] | 66 | bool shouldWalkTypesOfTypeLocs() const { return false; } | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 67 |  | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 68 | //------------------------------------------------------------------------ | 
|  | 69 | // Recording occurrences of (unexpanded) parameter packs. | 
|  | 70 | //------------------------------------------------------------------------ | 
|  | 71 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 72 | /// Record occurrences of template type parameter packs. | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 73 | bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { | 
|  | 74 | if (TL.getTypePtr()->isParameterPack()) | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 75 | addUnexpanded(TL.getTypePtr(), TL.getNameLoc()); | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 76 | return true; | 
|  | 77 | } | 
|  | 78 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 79 | /// Record occurrences of template type parameter packs | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 80 | /// when we don't have proper source-location information for | 
|  | 81 | /// them. | 
|  | 82 | /// | 
|  | 83 | /// Ideally, this routine would never be used. | 
|  | 84 | bool VisitTemplateTypeParmType(TemplateTypeParmType *T) { | 
|  | 85 | if (T->isParameterPack()) | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 86 | addUnexpanded(T); | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 87 |  | 
|  | 88 | return true; | 
|  | 89 | } | 
|  | 90 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 91 | /// Record occurrences of function and non-type template | 
| Douglas Gregor | da3cc0d | 2010-12-23 23:51:58 +0000 | [diff] [blame] | 92 | /// parameter packs in an expression. | 
|  | 93 | bool VisitDeclRefExpr(DeclRefExpr *E) { | 
| Douglas Gregor | f301011 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 94 | if (E->getDecl()->isParameterPack()) | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 95 | addUnexpanded(E->getDecl(), E->getLocation()); | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 96 |  | 
| Douglas Gregor | da3cc0d | 2010-12-23 23:51:58 +0000 | [diff] [blame] | 97 | return true; | 
|  | 98 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 99 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 100 | /// Record occurrences of template template parameter packs. | 
| Douglas Gregor | f550077 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 101 | bool TraverseTemplateName(TemplateName Template) { | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 102 | if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( | 
|  | 103 | Template.getAsTemplateDecl())) { | 
| Douglas Gregor | f550077 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 104 | if (TTP->isParameterPack()) | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 105 | addUnexpanded(TTP); | 
|  | 106 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 107 |  | 
| Douglas Gregor | f550077 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 108 | return inherited::TraverseTemplateName(Template); | 
|  | 109 | } | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 110 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 111 | /// Suppress traversal into Objective-C container literal | 
| Ted Kremenek | e65b086 | 2012-03-06 20:05:56 +0000 | [diff] [blame] | 112 | /// elements that are pack expansions. | 
|  | 113 | bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { | 
|  | 114 | if (!E->containsUnexpandedParameterPack()) | 
|  | 115 | return true; | 
|  | 116 |  | 
|  | 117 | for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { | 
|  | 118 | ObjCDictionaryElement Element = E->getKeyValueElement(I); | 
|  | 119 | if (Element.isPackExpansion()) | 
|  | 120 | continue; | 
|  | 121 |  | 
|  | 122 | TraverseStmt(Element.Key); | 
|  | 123 | TraverseStmt(Element.Value); | 
|  | 124 | } | 
|  | 125 | return true; | 
|  | 126 | } | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 127 | //------------------------------------------------------------------------ | 
|  | 128 | // Pruning the search for unexpanded parameter packs. | 
|  | 129 | //------------------------------------------------------------------------ | 
|  | 130 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 131 | /// Suppress traversal into statements and expressions that | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 132 | /// do not contain unexpanded parameter packs. | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 133 | bool TraverseStmt(Stmt *S) { | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 134 | Expr *E = dyn_cast_or_null<Expr>(S); | 
|  | 135 | if ((E && E->containsUnexpandedParameterPack()) || InLambda) | 
|  | 136 | return inherited::TraverseStmt(S); | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 137 |  | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 138 | return true; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 139 | } | 
|  | 140 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 141 | /// Suppress traversal into types that do not contain | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 142 | /// unexpanded parameter packs. | 
|  | 143 | bool TraverseType(QualType T) { | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 144 | if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda) | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 145 | return inherited::TraverseType(T); | 
|  | 146 |  | 
|  | 147 | return true; | 
|  | 148 | } | 
|  | 149 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 150 | /// Suppress traversal into types with location information | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 151 | /// that do not contain unexpanded parameter packs. | 
|  | 152 | bool TraverseTypeLoc(TypeLoc TL) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 153 | if ((!TL.getType().isNull() && | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 154 | TL.getType()->containsUnexpandedParameterPack()) || | 
|  | 155 | InLambda) | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 156 | return inherited::TraverseTypeLoc(TL); | 
|  | 157 |  | 
|  | 158 | return true; | 
|  | 159 | } | 
|  | 160 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 161 | /// Suppress traversal of parameter packs. | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 162 | bool TraverseDecl(Decl *D) { | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 163 | // A function parameter pack is a pack expansion, so cannot contain | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 164 | // an unexpanded parameter pack. Likewise for a template parameter | 
|  | 165 | // pack that contains any references to other packs. | 
| Brian Gesiak | 7dda73a | 2019-01-07 03:25:59 +0000 | [diff] [blame] | 166 | if (D && D->isParameterPack()) | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 167 | return true; | 
|  | 168 |  | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 169 | return inherited::TraverseDecl(D); | 
|  | 170 | } | 
| Douglas Gregor | a8461bb | 2010-12-15 21:57:59 +0000 | [diff] [blame] | 171 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 172 | /// Suppress traversal of pack-expanded attributes. | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 173 | bool TraverseAttr(Attr *A) { | 
|  | 174 | if (A->isPackExpansion()) | 
|  | 175 | return true; | 
|  | 176 |  | 
|  | 177 | return inherited::TraverseAttr(A); | 
|  | 178 | } | 
|  | 179 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 180 | /// Suppress traversal of pack expansion expressions and types. | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 181 | ///@{ | 
|  | 182 | bool TraversePackExpansionType(PackExpansionType *T) { return true; } | 
|  | 183 | bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; } | 
|  | 184 | bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; } | 
|  | 185 | bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; } | 
|  | 186 |  | 
|  | 187 | ///@} | 
|  | 188 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 189 | /// Suppress traversal of using-declaration pack expansion. | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 190 | bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { | 
|  | 191 | if (D->isPackExpansion()) | 
|  | 192 | return true; | 
|  | 193 |  | 
|  | 194 | return inherited::TraverseUnresolvedUsingValueDecl(D); | 
|  | 195 | } | 
|  | 196 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 197 | /// Suppress traversal of using-declaration pack expansion. | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 198 | bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { | 
|  | 199 | if (D->isPackExpansion()) | 
|  | 200 | return true; | 
|  | 201 |  | 
|  | 202 | return inherited::TraverseUnresolvedUsingTypenameDecl(D); | 
| Douglas Gregor | a8461bb | 2010-12-15 21:57:59 +0000 | [diff] [blame] | 203 | } | 
| Douglas Gregor | eb29d18 | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 204 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 205 | /// Suppress traversal of template argument pack expansions. | 
| Douglas Gregor | eb29d18 | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 206 | bool TraverseTemplateArgument(const TemplateArgument &Arg) { | 
|  | 207 | if (Arg.isPackExpansion()) | 
|  | 208 | return true; | 
|  | 209 |  | 
|  | 210 | return inherited::TraverseTemplateArgument(Arg); | 
|  | 211 | } | 
|  | 212 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 213 | /// Suppress traversal of template argument pack expansions. | 
| Douglas Gregor | eb29d18 | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 214 | bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { | 
|  | 215 | if (ArgLoc.getArgument().isPackExpansion()) | 
|  | 216 | return true; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 217 |  | 
| Douglas Gregor | eb29d18 | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 218 | return inherited::TraverseTemplateArgumentLoc(ArgLoc); | 
|  | 219 | } | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 220 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 221 | /// Suppress traversal of base specifier pack expansions. | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 222 | bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { | 
|  | 223 | if (Base.isPackExpansion()) | 
|  | 224 | return true; | 
|  | 225 |  | 
|  | 226 | return inherited::TraverseCXXBaseSpecifier(Base); | 
|  | 227 | } | 
|  | 228 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 229 | /// Suppress traversal of mem-initializer pack expansions. | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 230 | bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { | 
|  | 231 | if (Init->isPackExpansion()) | 
|  | 232 | return true; | 
|  | 233 |  | 
|  | 234 | return inherited::TraverseConstructorInitializer(Init); | 
|  | 235 | } | 
|  | 236 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 237 | /// Note whether we're traversing a lambda containing an unexpanded | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 238 | /// parameter pack. In this case, the unexpanded pack can occur anywhere, | 
|  | 239 | /// including all the places where we normally wouldn't look. Within a | 
|  | 240 | /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit | 
|  | 241 | /// outside an expression. | 
|  | 242 | bool TraverseLambdaExpr(LambdaExpr *Lambda) { | 
|  | 243 | // The ContainsUnexpandedParameterPack bit on a lambda is always correct, | 
|  | 244 | // even if it's contained within another lambda. | 
|  | 245 | if (!Lambda->containsUnexpandedParameterPack()) | 
|  | 246 | return true; | 
|  | 247 |  | 
|  | 248 | bool WasInLambda = InLambda; | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 249 | unsigned OldDepthLimit = DepthLimit; | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 250 |  | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 251 | InLambda = true; | 
|  | 252 | if (auto *TPL = Lambda->getTemplateParameterList()) | 
|  | 253 | DepthLimit = TPL->getDepth(); | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 254 |  | 
|  | 255 | inherited::TraverseLambdaExpr(Lambda); | 
|  | 256 |  | 
|  | 257 | InLambda = WasInLambda; | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 258 | DepthLimit = OldDepthLimit; | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 259 | return true; | 
|  | 260 | } | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 261 |  | 
|  | 262 | /// Suppress traversal within pack expansions in lambda captures. | 
|  | 263 | bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C, | 
|  | 264 | Expr *Init) { | 
|  | 265 | if (C->isPackExpansion()) | 
|  | 266 | return true; | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 267 |  | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 268 | return inherited::TraverseLambdaCapture(Lambda, C, Init); | 
|  | 269 | } | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 270 | }; | 
| Alexander Kornienko | ab9db51 | 2015-06-22 23:07:51 +0000 | [diff] [blame] | 271 | } | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 272 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 273 | /// Determine whether it's possible for an unexpanded parameter pack to | 
| Richard Smith | 36ee9fb | 2014-08-11 23:30:23 +0000 | [diff] [blame] | 274 | /// be valid in this location. This only happens when we're in a declaration | 
|  | 275 | /// that is nested within an expression that could be expanded, such as a | 
|  | 276 | /// lambda-expression within a function call. | 
|  | 277 | /// | 
|  | 278 | /// This is conservatively correct, but may claim that some unexpanded packs are | 
|  | 279 | /// permitted when they are not. | 
|  | 280 | bool Sema::isUnexpandedParameterPackPermitted() { | 
|  | 281 | for (auto *SI : FunctionScopes) | 
|  | 282 | if (isa<sema::LambdaScopeInfo>(SI)) | 
|  | 283 | return true; | 
|  | 284 | return false; | 
|  | 285 | } | 
|  | 286 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 287 | /// Diagnose all of the unexpanded parameter packs in the given | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 288 | /// vector. | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 289 | bool | 
| Douglas Gregor | 4a2a8f7 | 2011-10-25 03:44:56 +0000 | [diff] [blame] | 290 | Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, | 
|  | 291 | UnexpandedParameterPackContext UPPC, | 
| Bill Wendling | 8ac06af | 2012-02-22 09:38:11 +0000 | [diff] [blame] | 292 | ArrayRef<UnexpandedParameterPack> Unexpanded) { | 
| Douglas Gregor | 4a2a8f7 | 2011-10-25 03:44:56 +0000 | [diff] [blame] | 293 | if (Unexpanded.empty()) | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 294 | return false; | 
|  | 295 |  | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 296 | // If we are within a lambda expression and referencing a pack that is not | 
|  | 297 | // a parameter of the lambda itself, that lambda contains an unexpanded | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 298 | // parameter pack, and we are done. | 
|  | 299 | // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it | 
|  | 300 | // later. | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 301 | SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences; | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 302 | for (unsigned N = FunctionScopes.size(); N; --N) { | 
| Richard Smith | 6eb9b9e | 2018-02-03 00:44:57 +0000 | [diff] [blame] | 303 | sema::FunctionScopeInfo *Func = FunctionScopes[N-1]; | 
|  | 304 | // We do not permit pack expansion that would duplicate a statement | 
|  | 305 | // expression, not even within a lambda. | 
|  | 306 | // FIXME: We could probably support this for statement expressions that do | 
|  | 307 | // not contain labels, and for pack expansions that expand both the stmt | 
|  | 308 | // expr and the enclosing lambda. | 
|  | 309 | if (std::any_of( | 
|  | 310 | Func->CompoundScopes.begin(), Func->CompoundScopes.end(), | 
|  | 311 | [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) | 
|  | 312 | break; | 
|  | 313 |  | 
|  | 314 | if (auto *LSI = dyn_cast<sema::LambdaScopeInfo>(Func)) { | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 315 | if (N == FunctionScopes.size()) { | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 316 | for (auto &Pack : Unexpanded) { | 
|  | 317 | auto *VD = dyn_cast_or_null<VarDecl>( | 
|  | 318 | Pack.first.dyn_cast<NamedDecl *>()); | 
|  | 319 | if (VD && VD->getDeclContext() == LSI->CallOperator) | 
|  | 320 | LambdaParamPackReferences.push_back(Pack); | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 321 | } | 
|  | 322 | } | 
|  | 323 |  | 
| Richard Smith | f26d551 | 2017-08-15 22:58:45 +0000 | [diff] [blame] | 324 | // If we have references to a parameter pack of the innermost enclosing | 
|  | 325 | // lambda, only diagnose those ones. We don't know whether any other | 
|  | 326 | // unexpanded parameters referenced herein are actually unexpanded; | 
|  | 327 | // they might be expanded at an outer level. | 
|  | 328 | if (!LambdaParamPackReferences.empty()) { | 
|  | 329 | Unexpanded = LambdaParamPackReferences; | 
| Richard Smith | 78a07ba | 2017-08-15 19:11:21 +0000 | [diff] [blame] | 330 | break; | 
|  | 331 | } | 
|  | 332 |  | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 333 | LSI->ContainsUnexpandedParameterPack = true; | 
|  | 334 | return false; | 
|  | 335 | } | 
|  | 336 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 337 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 338 | SmallVector<SourceLocation, 4> Locations; | 
|  | 339 | SmallVector<IdentifierInfo *, 4> Names; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 340 | llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown; | 
|  | 341 |  | 
|  | 342 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { | 
| Craig Topper | c3ec149 | 2014-05-26 06:22:03 +0000 | [diff] [blame] | 343 | IdentifierInfo *Name = nullptr; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 344 | if (const TemplateTypeParmType *TTP | 
|  | 345 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) | 
| Chandler Carruth | dde65ea | 2011-05-01 01:05:51 +0000 | [diff] [blame] | 346 | Name = TTP->getIdentifier(); | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 347 | else | 
|  | 348 | Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier(); | 
|  | 349 |  | 
| David Blaikie | 82e95a3 | 2014-11-19 07:49:47 +0000 | [diff] [blame] | 350 | if (Name && NamesKnown.insert(Name).second) | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 351 | Names.push_back(Name); | 
|  | 352 |  | 
|  | 353 | if (Unexpanded[I].second.isValid()) | 
|  | 354 | Locations.push_back(Unexpanded[I].second); | 
|  | 355 | } | 
|  | 356 |  | 
| Benjamin Kramer | 3a8650a | 2015-03-27 17:23:14 +0000 | [diff] [blame] | 357 | DiagnosticBuilder DB = Diag(Loc, diag::err_unexpanded_parameter_pack) | 
|  | 358 | << (int)UPPC << (int)Names.size(); | 
|  | 359 | for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I) | 
|  | 360 | DB << Names[I]; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 361 |  | 
|  | 362 | for (unsigned I = 0, N = Locations.size(); I != N; ++I) | 
|  | 363 | DB << SourceRange(Locations[I]); | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 364 | return true; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 365 | } | 
|  | 366 |  | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 367 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 368 | TypeSourceInfo *T, | 
|  | 369 | UnexpandedParameterPackContext UPPC) { | 
|  | 370 | // C++0x [temp.variadic]p5: | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 371 | //   An appearance of a name of a parameter pack that is not expanded is | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 372 | //   ill-formed. | 
|  | 373 | if (!T->getType()->containsUnexpandedParameterPack()) | 
|  | 374 | return false; | 
|  | 375 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 376 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 377 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc( | 
|  | 378 | T->getTypeLoc()); | 
|  | 379 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 380 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 381 | } | 
|  | 382 |  | 
|  | 383 | bool Sema::DiagnoseUnexpandedParameterPack(Expr *E, | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 384 | UnexpandedParameterPackContext UPPC) { | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 385 | // C++0x [temp.variadic]p5: | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 386 | //   An appearance of a name of a parameter pack that is not expanded is | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 387 | //   ill-formed. | 
|  | 388 | if (!E->containsUnexpandedParameterPack()) | 
|  | 389 | return false; | 
|  | 390 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 391 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
| Douglas Gregor | 1da294a | 2010-12-15 19:43:21 +0000 | [diff] [blame] | 392 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E); | 
|  | 393 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 394 | return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded); | 
| Douglas Gregor | b55fdf8 | 2010-12-15 17:38:57 +0000 | [diff] [blame] | 395 | } | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 396 |  | 
|  | 397 | bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, | 
|  | 398 | UnexpandedParameterPackContext UPPC) { | 
|  | 399 | // C++0x [temp.variadic]p5: | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 400 | //   An appearance of a name of a parameter pack that is not expanded is | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 401 | //   ill-formed. | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 402 | if (!SS.getScopeRep() || | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 403 | !SS.getScopeRep()->containsUnexpandedParameterPack()) | 
|  | 404 | return false; | 
|  | 405 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 406 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 407 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
|  | 408 | .TraverseNestedNameSpecifier(SS.getScopeRep()); | 
|  | 409 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 410 | return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(), | 
|  | 411 | UPPC, Unexpanded); | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 412 | } | 
|  | 413 |  | 
|  | 414 | bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, | 
|  | 415 | UnexpandedParameterPackContext UPPC) { | 
|  | 416 | // C++0x [temp.variadic]p5: | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 417 | //   An appearance of a name of a parameter pack that is not expanded is | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 418 | //   ill-formed. | 
|  | 419 | switch (NameInfo.getName().getNameKind()) { | 
|  | 420 | case DeclarationName::Identifier: | 
|  | 421 | case DeclarationName::ObjCZeroArgSelector: | 
|  | 422 | case DeclarationName::ObjCOneArgSelector: | 
|  | 423 | case DeclarationName::ObjCMultiArgSelector: | 
|  | 424 | case DeclarationName::CXXOperatorName: | 
|  | 425 | case DeclarationName::CXXLiteralOperatorName: | 
|  | 426 | case DeclarationName::CXXUsingDirective: | 
| Richard Smith | 3584515 | 2017-02-07 01:37:30 +0000 | [diff] [blame] | 427 | case DeclarationName::CXXDeductionGuideName: | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 428 | return false; | 
|  | 429 |  | 
|  | 430 | case DeclarationName::CXXConstructorName: | 
|  | 431 | case DeclarationName::CXXDestructorName: | 
|  | 432 | case DeclarationName::CXXConversionFunctionName: | 
| Douglas Gregor | 062ecac | 2010-12-16 17:19:19 +0000 | [diff] [blame] | 433 | // FIXME: We shouldn't need this null check! | 
| Douglas Gregor | 6ab34af | 2010-12-16 01:40:04 +0000 | [diff] [blame] | 434 | if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) | 
|  | 435 | return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC); | 
|  | 436 |  | 
|  | 437 | if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack()) | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 438 | return false; | 
| Douglas Gregor | 6ab34af | 2010-12-16 01:40:04 +0000 | [diff] [blame] | 439 |  | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 440 | break; | 
|  | 441 | } | 
|  | 442 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 443 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 444 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
| Douglas Gregor | 6ab34af | 2010-12-16 01:40:04 +0000 | [diff] [blame] | 445 | .TraverseType(NameInfo.getName().getCXXNameType()); | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 446 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 447 | return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded); | 
| Douglas Gregor | c435653 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 448 | } | 
| Douglas Gregor | 6ff1fbf | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 449 |  | 
|  | 450 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, | 
|  | 451 | TemplateName Template, | 
|  | 452 | UnexpandedParameterPackContext UPPC) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 453 |  | 
| Douglas Gregor | 6ff1fbf | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 454 | if (Template.isNull() || !Template.containsUnexpandedParameterPack()) | 
|  | 455 | return false; | 
|  | 456 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 457 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
| Douglas Gregor | 6ff1fbf | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 458 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
|  | 459 | .TraverseTemplateName(Template); | 
|  | 460 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 461 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); | 
| Douglas Gregor | 6ff1fbf | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 462 | } | 
|  | 463 |  | 
| Douglas Gregor | 1440693 | 2011-01-03 20:35:03 +0000 | [diff] [blame] | 464 | bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, | 
|  | 465 | UnexpandedParameterPackContext UPPC) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 466 | if (Arg.getArgument().isNull() || | 
| Douglas Gregor | 1440693 | 2011-01-03 20:35:03 +0000 | [diff] [blame] | 467 | !Arg.getArgument().containsUnexpandedParameterPack()) | 
|  | 468 | return false; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 469 |  | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 470 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
| Douglas Gregor | 1440693 | 2011-01-03 20:35:03 +0000 | [diff] [blame] | 471 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
|  | 472 | .TraverseTemplateArgumentLoc(Arg); | 
|  | 473 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); | 
| Richard Smith | 2589b980 | 2012-07-25 03:56:55 +0000 | [diff] [blame] | 474 | return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded); | 
| Douglas Gregor | 1440693 | 2011-01-03 20:35:03 +0000 | [diff] [blame] | 475 | } | 
|  | 476 |  | 
| Douglas Gregor | 0f3feb4 | 2010-12-22 21:19:48 +0000 | [diff] [blame] | 477 | void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg, | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 478 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | 
| Douglas Gregor | 0f3feb4 | 2010-12-22 21:19:48 +0000 | [diff] [blame] | 479 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
|  | 480 | .TraverseTemplateArgument(Arg); | 
|  | 481 | } | 
|  | 482 |  | 
| Douglas Gregor | 840bd6c | 2010-12-20 22:05:00 +0000 | [diff] [blame] | 483 | void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 484 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | 
| Douglas Gregor | 840bd6c | 2010-12-20 22:05:00 +0000 | [diff] [blame] | 485 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
|  | 486 | .TraverseTemplateArgumentLoc(Arg); | 
|  | 487 | } | 
|  | 488 |  | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 489 | void Sema::collectUnexpandedParameterPacks(QualType T, | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 490 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 491 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T); | 
|  | 492 | } | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 493 |  | 
| Douglas Gregor | 752a595 | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 494 | void Sema::collectUnexpandedParameterPacks(TypeLoc TL, | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 495 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 496 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL); | 
| Richard Smith | 22a250c | 2016-12-19 04:08:53 +0000 | [diff] [blame] | 497 | } | 
|  | 498 |  | 
| Richard Smith | 151c456 | 2016-12-20 21:35:28 +0000 | [diff] [blame] | 499 | void Sema::collectUnexpandedParameterPacks( | 
|  | 500 | NestedNameSpecifierLoc NNS, | 
|  | 501 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | 
|  | 502 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
|  | 503 | .TraverseNestedNameSpecifierLoc(NNS); | 
|  | 504 | } | 
|  | 505 |  | 
|  | 506 | void Sema::collectUnexpandedParameterPacks( | 
|  | 507 | const DeclarationNameInfo &NameInfo, | 
|  | 508 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | 
| Douglas Gregor | 4a2a8f7 | 2011-10-25 03:44:56 +0000 | [diff] [blame] | 509 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | 
|  | 510 | .TraverseDeclarationNameInfo(NameInfo); | 
|  | 511 | } | 
|  | 512 |  | 
|  | 513 |  | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 514 | ParsedTemplateArgument | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 515 | Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, | 
|  | 516 | SourceLocation EllipsisLoc) { | 
|  | 517 | if (Arg.isInvalid()) | 
|  | 518 | return Arg; | 
|  | 519 |  | 
|  | 520 | switch (Arg.getKind()) { | 
|  | 521 | case ParsedTemplateArgument::Type: { | 
|  | 522 | TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc); | 
|  | 523 | if (Result.isInvalid()) | 
|  | 524 | return ParsedTemplateArgument(); | 
|  | 525 |  | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 526 | return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(), | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 527 | Arg.getLocation()); | 
|  | 528 | } | 
|  | 529 |  | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 530 | case ParsedTemplateArgument::NonType: { | 
|  | 531 | ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc); | 
|  | 532 | if (Result.isInvalid()) | 
|  | 533 | return ParsedTemplateArgument(); | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 534 |  | 
|  | 535 | return ParsedTemplateArgument(Arg.getKind(), Result.get(), | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 536 | Arg.getLocation()); | 
|  | 537 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 538 |  | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 539 | case ParsedTemplateArgument::Template: | 
| Douglas Gregor | eb29d18 | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 540 | if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) { | 
|  | 541 | SourceRange R(Arg.getLocation()); | 
|  | 542 | if (Arg.getScopeSpec().isValid()) | 
|  | 543 | R.setBegin(Arg.getScopeSpec().getBeginLoc()); | 
|  | 544 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | 
|  | 545 | << R; | 
|  | 546 | return ParsedTemplateArgument(); | 
|  | 547 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 548 |  | 
| Douglas Gregor | eb29d18 | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 549 | return Arg.getTemplatePackExpansion(EllipsisLoc); | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 550 | } | 
|  | 551 | llvm_unreachable("Unhandled template argument kind?"); | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 552 | } | 
|  | 553 |  | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 554 | TypeResult Sema::ActOnPackExpansion(ParsedType Type, | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 555 | SourceLocation EllipsisLoc) { | 
|  | 556 | TypeSourceInfo *TSInfo; | 
|  | 557 | GetTypeFromParser(Type, &TSInfo); | 
|  | 558 | if (!TSInfo) | 
|  | 559 | return true; | 
|  | 560 |  | 
| David Blaikie | 7a30dc5 | 2013-02-21 01:47:18 +0000 | [diff] [blame] | 561 | TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None); | 
| Douglas Gregor | 840bd6c | 2010-12-20 22:05:00 +0000 | [diff] [blame] | 562 | if (!TSResult) | 
|  | 563 | return true; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 564 |  | 
| Douglas Gregor | 840bd6c | 2010-12-20 22:05:00 +0000 | [diff] [blame] | 565 | return CreateParsedType(TSResult->getType(), TSResult); | 
|  | 566 | } | 
|  | 567 |  | 
| David Blaikie | 05785d1 | 2013-02-20 22:23:23 +0000 | [diff] [blame] | 568 | TypeSourceInfo * | 
|  | 569 | Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, | 
|  | 570 | Optional<unsigned> NumExpansions) { | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 571 | // Create the pack expansion type and source-location information. | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 572 | QualType Result = CheckPackExpansion(Pattern->getType(), | 
| Douglas Gregor | 822d030 | 2011-01-12 17:07:58 +0000 | [diff] [blame] | 573 | Pattern->getTypeLoc().getSourceRange(), | 
| Douglas Gregor | 0dca5fd | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 574 | EllipsisLoc, NumExpansions); | 
| Douglas Gregor | 822d030 | 2011-01-12 17:07:58 +0000 | [diff] [blame] | 575 | if (Result.isNull()) | 
| Craig Topper | c3ec149 | 2014-05-26 06:22:03 +0000 | [diff] [blame] | 576 | return nullptr; | 
| Eli Friedman | 7152fbe | 2013-06-07 20:31:48 +0000 | [diff] [blame] | 577 |  | 
|  | 578 | TypeLocBuilder TLB; | 
|  | 579 | TLB.pushFullCopy(Pattern->getTypeLoc()); | 
|  | 580 | PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result); | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 581 | TL.setEllipsisLoc(EllipsisLoc); | 
| Eli Friedman | 7152fbe | 2013-06-07 20:31:48 +0000 | [diff] [blame] | 582 |  | 
|  | 583 | return TLB.getTypeSourceInfo(Context, Result); | 
| Douglas Gregor | d2fa766 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 584 | } | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 585 |  | 
| David Blaikie | 05785d1 | 2013-02-20 22:23:23 +0000 | [diff] [blame] | 586 | QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, | 
| Douglas Gregor | 0dca5fd | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 587 | SourceLocation EllipsisLoc, | 
| David Blaikie | 05785d1 | 2013-02-20 22:23:23 +0000 | [diff] [blame] | 588 | Optional<unsigned> NumExpansions) { | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 589 | // C++11 [temp.variadic]p5: | 
| Douglas Gregor | 822d030 | 2011-01-12 17:07:58 +0000 | [diff] [blame] | 590 | //   The pattern of a pack expansion shall name one or more | 
|  | 591 | //   parameter packs that are not expanded by a nested pack | 
|  | 592 | //   expansion. | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 593 | // | 
|  | 594 | // A pattern containing a deduced type can't occur "naturally" but arises in | 
|  | 595 | // the desugaring of an init-capture pack. | 
|  | 596 | if (!Pattern->containsUnexpandedParameterPack() && | 
|  | 597 | !Pattern->getContainedDeducedType()) { | 
| Douglas Gregor | 822d030 | 2011-01-12 17:07:58 +0000 | [diff] [blame] | 598 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | 
|  | 599 | << PatternRange; | 
|  | 600 | return QualType(); | 
|  | 601 | } | 
|  | 602 |  | 
| Douglas Gregor | 0dca5fd | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 603 | return Context.getPackExpansionType(Pattern, NumExpansions); | 
| Douglas Gregor | 822d030 | 2011-01-12 17:07:58 +0000 | [diff] [blame] | 604 | } | 
|  | 605 |  | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 606 | ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { | 
| David Blaikie | 7a30dc5 | 2013-02-21 01:47:18 +0000 | [diff] [blame] | 607 | return CheckPackExpansion(Pattern, EllipsisLoc, None); | 
| Douglas Gregor | b884000 | 2011-01-14 21:20:45 +0000 | [diff] [blame] | 608 | } | 
|  | 609 |  | 
|  | 610 | ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, | 
| David Blaikie | 05785d1 | 2013-02-20 22:23:23 +0000 | [diff] [blame] | 611 | Optional<unsigned> NumExpansions) { | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 612 | if (!Pattern) | 
|  | 613 | return ExprError(); | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 614 |  | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 615 | // C++0x [temp.variadic]p5: | 
|  | 616 | //   The pattern of a pack expansion shall name one or more | 
|  | 617 | //   parameter packs that are not expanded by a nested pack | 
|  | 618 | //   expansion. | 
|  | 619 | if (!Pattern->containsUnexpandedParameterPack()) { | 
|  | 620 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | 
|  | 621 | << Pattern->getSourceRange(); | 
| Sam McCall | 0afffab | 2019-07-16 10:30:21 +0000 | [diff] [blame] | 622 | CorrectDelayedTyposInExpr(Pattern); | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 623 | return ExprError(); | 
|  | 624 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 625 |  | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 626 | // Create the pack expansion expression and source-location information. | 
| Nikola Smiljanic | 03ff259 | 2014-05-29 14:05:12 +0000 | [diff] [blame] | 627 | return new (Context) | 
|  | 628 | PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions); | 
| Douglas Gregor | e8e9dd6 | 2011-01-03 17:17:50 +0000 | [diff] [blame] | 629 | } | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 630 |  | 
| David Blaikie | 05785d1 | 2013-02-20 22:23:23 +0000 | [diff] [blame] | 631 | bool Sema::CheckParameterPacksForExpansion( | 
|  | 632 | SourceLocation EllipsisLoc, SourceRange PatternRange, | 
|  | 633 | ArrayRef<UnexpandedParameterPack> Unexpanded, | 
|  | 634 | const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, | 
|  | 635 | bool &RetainExpansion, Optional<unsigned> &NumExpansions) { | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 636 | ShouldExpand = true; | 
| Douglas Gregor | a8bac7f | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 637 | RetainExpansion = false; | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 638 | std::pair<IdentifierInfo *, SourceLocation> FirstPack; | 
|  | 639 | bool HaveFirstPack = false; | 
| Richard Smith | 4a8f351 | 2018-07-19 19:00:37 +0000 | [diff] [blame] | 640 | Optional<unsigned> NumPartialExpansions; | 
|  | 641 | SourceLocation PartiallySubstitutedPackLoc; | 
|  | 642 |  | 
| David Blaikie | b9c168a | 2011-09-22 02:34:54 +0000 | [diff] [blame] | 643 | for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(), | 
|  | 644 | end = Unexpanded.end(); | 
|  | 645 | i != end; ++i) { | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 646 | // Compute the depth and index for this parameter pack. | 
| Ted Kremenek | 582a099 | 2011-01-23 17:04:59 +0000 | [diff] [blame] | 647 | unsigned Depth = 0, Index = 0; | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 648 | IdentifierInfo *Name; | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 649 | bool IsVarDeclPack = false; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 650 |  | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 651 | if (const TemplateTypeParmType *TTP | 
| David Blaikie | b9c168a | 2011-09-22 02:34:54 +0000 | [diff] [blame] | 652 | = i->first.dyn_cast<const TemplateTypeParmType *>()) { | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 653 | Depth = TTP->getDepth(); | 
|  | 654 | Index = TTP->getIndex(); | 
| Chandler Carruth | dde65ea | 2011-05-01 01:05:51 +0000 | [diff] [blame] | 655 | Name = TTP->getIdentifier(); | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 656 | } else { | 
| David Blaikie | b9c168a | 2011-09-22 02:34:54 +0000 | [diff] [blame] | 657 | NamedDecl *ND = i->first.get<NamedDecl *>(); | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 658 | if (isa<VarDecl>(ND)) | 
|  | 659 | IsVarDeclPack = true; | 
| Douglas Gregor | a8bac7f | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 660 | else | 
| Benjamin Kramer | 867ea1d | 2014-03-02 13:01:17 +0000 | [diff] [blame] | 661 | std::tie(Depth, Index) = getDepthAndIndex(ND); | 
|  | 662 |  | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 663 | Name = ND->getIdentifier(); | 
|  | 664 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 665 |  | 
| Douglas Gregor | f301011 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 666 | // Determine the size of this argument pack. | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 667 | unsigned NewPackSize; | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 668 | if (IsVarDeclPack) { | 
| Douglas Gregor | f301011 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 669 | // Figure out whether we're instantiating to an argument pack or not. | 
|  | 670 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 671 |  | 
| Douglas Gregor | f301011 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 672 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation | 
|  | 673 | = CurrentInstantiationScope->findInstantiationOf( | 
| David Blaikie | b9c168a | 2011-09-22 02:34:54 +0000 | [diff] [blame] | 674 | i->first.get<NamedDecl *>()); | 
| Chris Lattner | 15a776f | 2011-02-17 19:38:27 +0000 | [diff] [blame] | 675 | if (Instantiation->is<DeclArgumentPack *>()) { | 
| Douglas Gregor | f301011 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 676 | // We could expand this function parameter pack. | 
|  | 677 | NewPackSize = Instantiation->get<DeclArgumentPack *>()->size(); | 
|  | 678 | } else { | 
|  | 679 | // We can't expand this function parameter pack, so we can't expand | 
|  | 680 | // the pack expansion. | 
|  | 681 | ShouldExpand = false; | 
|  | 682 | continue; | 
|  | 683 | } | 
|  | 684 | } else { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 685 | // If we don't have a template argument at this depth/index, then we | 
|  | 686 | // cannot expand the pack expansion. Make a note of this, but we still | 
| Douglas Gregor | f301011 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 687 | // want to check any parameter packs we *do* have arguments for. | 
|  | 688 | if (Depth >= TemplateArgs.getNumLevels() || | 
|  | 689 | !TemplateArgs.hasTemplateArgument(Depth, Index)) { | 
|  | 690 | ShouldExpand = false; | 
|  | 691 | continue; | 
|  | 692 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 693 |  | 
| Douglas Gregor | f301011 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 694 | // Determine the size of the argument pack. | 
|  | 695 | NewPackSize = TemplateArgs(Depth, Index).pack_size(); | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 696 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 697 |  | 
| Douglas Gregor | a8bac7f | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 698 | // C++0x [temp.arg.explicit]p9: | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 699 | //   Template argument deduction can extend the sequence of template | 
| Douglas Gregor | a8bac7f | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 700 | //   arguments corresponding to a template parameter pack, even when the | 
|  | 701 | //   sequence contains explicitly specified template arguments. | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 702 | if (!IsVarDeclPack && CurrentInstantiationScope) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 703 | if (NamedDecl *PartialPack | 
| Douglas Gregor | 63dad4d | 2011-01-20 23:15:49 +0000 | [diff] [blame] | 704 | = CurrentInstantiationScope->getPartiallySubstitutedPack()){ | 
|  | 705 | unsigned PartialDepth, PartialIndex; | 
| Benjamin Kramer | 867ea1d | 2014-03-02 13:01:17 +0000 | [diff] [blame] | 706 | std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack); | 
| Richard Smith | 4a8f351 | 2018-07-19 19:00:37 +0000 | [diff] [blame] | 707 | if (PartialDepth == Depth && PartialIndex == Index) { | 
| Douglas Gregor | 63dad4d | 2011-01-20 23:15:49 +0000 | [diff] [blame] | 708 | RetainExpansion = true; | 
| Richard Smith | 4a8f351 | 2018-07-19 19:00:37 +0000 | [diff] [blame] | 709 | // We don't actually know the new pack size yet. | 
|  | 710 | NumPartialExpansions = NewPackSize; | 
|  | 711 | PartiallySubstitutedPackLoc = i->second; | 
|  | 712 | continue; | 
|  | 713 | } | 
| Douglas Gregor | 63dad4d | 2011-01-20 23:15:49 +0000 | [diff] [blame] | 714 | } | 
| Douglas Gregor | a8bac7f | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 715 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 716 |  | 
| Douglas Gregor | 0dca5fd | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 717 | if (!NumExpansions) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 718 | // The is the first pack we've seen for which we have an argument. | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 719 | // Record it. | 
|  | 720 | NumExpansions = NewPackSize; | 
|  | 721 | FirstPack.first = Name; | 
| David Blaikie | b9c168a | 2011-09-22 02:34:54 +0000 | [diff] [blame] | 722 | FirstPack.second = i->second; | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 723 | HaveFirstPack = true; | 
|  | 724 | continue; | 
|  | 725 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 726 |  | 
| Douglas Gregor | 0dca5fd | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 727 | if (NewPackSize != *NumExpansions) { | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 728 | // C++0x [temp.variadic]p5: | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 729 | //   All of the parameter packs expanded by a pack expansion shall have | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 730 | //   the same number of arguments specified. | 
| Douglas Gregor | 0dca5fd | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 731 | if (HaveFirstPack) | 
|  | 732 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) | 
|  | 733 | << FirstPack.first << Name << *NumExpansions << NewPackSize | 
| David Blaikie | b9c168a | 2011-09-22 02:34:54 +0000 | [diff] [blame] | 734 | << SourceRange(FirstPack.second) << SourceRange(i->second); | 
| Douglas Gregor | 0dca5fd | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 735 | else | 
|  | 736 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) | 
|  | 737 | << Name << *NumExpansions << NewPackSize | 
| David Blaikie | b9c168a | 2011-09-22 02:34:54 +0000 | [diff] [blame] | 738 | << SourceRange(i->second); | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 739 | return true; | 
|  | 740 | } | 
|  | 741 | } | 
| Richard Smith | c5452ed | 2016-10-19 22:18:42 +0000 | [diff] [blame] | 742 |  | 
| Richard Smith | 4a8f351 | 2018-07-19 19:00:37 +0000 | [diff] [blame] | 743 | // If we're performing a partial expansion but we also have a full expansion, | 
|  | 744 | // expand to the number of common arguments. For example, given: | 
|  | 745 | // | 
|  | 746 | //   template<typename ...T> struct A { | 
|  | 747 | //     template<typename ...U> void f(pair<T, U>...); | 
|  | 748 | //   }; | 
|  | 749 | // | 
|  | 750 | // ... a call to 'A<int, int>().f<int>' should expand the pack once and | 
|  | 751 | // retain an expansion. | 
|  | 752 | if (NumPartialExpansions) { | 
|  | 753 | if (NumExpansions && *NumExpansions < *NumPartialExpansions) { | 
|  | 754 | NamedDecl *PartialPack = | 
|  | 755 | CurrentInstantiationScope->getPartiallySubstitutedPack(); | 
|  | 756 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial) | 
|  | 757 | << PartialPack << *NumPartialExpansions << *NumExpansions | 
|  | 758 | << SourceRange(PartiallySubstitutedPackLoc); | 
|  | 759 | return true; | 
|  | 760 | } | 
|  | 761 |  | 
|  | 762 | NumExpansions = NumPartialExpansions; | 
|  | 763 | } | 
|  | 764 |  | 
| Douglas Gregor | 76aca7b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 765 | return false; | 
|  | 766 | } | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 767 |  | 
| David Blaikie | 05785d1 | 2013-02-20 22:23:23 +0000 | [diff] [blame] | 768 | Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T, | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 769 | const MultiLevelTemplateArgumentList &TemplateArgs) { | 
|  | 770 | QualType Pattern = cast<PackExpansionType>(T)->getPattern(); | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 771 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 772 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); | 
|  | 773 |  | 
| David Blaikie | 05785d1 | 2013-02-20 22:23:23 +0000 | [diff] [blame] | 774 | Optional<unsigned> Result; | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 775 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { | 
|  | 776 | // Compute the depth and index for this parameter pack. | 
|  | 777 | unsigned Depth; | 
|  | 778 | unsigned Index; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 779 |  | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 780 | if (const TemplateTypeParmType *TTP | 
|  | 781 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { | 
|  | 782 | Depth = TTP->getDepth(); | 
|  | 783 | Index = TTP->getIndex(); | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 784 | } else { | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 785 | NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>(); | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 786 | if (isa<VarDecl>(ND)) { | 
|  | 787 | // Function parameter pack or init-capture pack. | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 788 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 789 |  | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 790 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation | 
|  | 791 | = CurrentInstantiationScope->findInstantiationOf( | 
|  | 792 | Unexpanded[I].first.get<NamedDecl *>()); | 
| Richard Smith | 198223b | 2012-07-18 01:29:05 +0000 | [diff] [blame] | 793 | if (Instantiation->is<Decl*>()) | 
|  | 794 | // The pattern refers to an unexpanded pack. We're not ready to expand | 
|  | 795 | // this pack yet. | 
| David Blaikie | 7a30dc5 | 2013-02-21 01:47:18 +0000 | [diff] [blame] | 796 | return None; | 
| Richard Smith | 198223b | 2012-07-18 01:29:05 +0000 | [diff] [blame] | 797 |  | 
|  | 798 | unsigned Size = Instantiation->get<DeclArgumentPack *>()->size(); | 
|  | 799 | assert((!Result || *Result == Size) && "inconsistent pack sizes"); | 
|  | 800 | Result = Size; | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 801 | continue; | 
|  | 802 | } | 
| Benjamin Kramer | 867ea1d | 2014-03-02 13:01:17 +0000 | [diff] [blame] | 803 |  | 
|  | 804 | std::tie(Depth, Index) = getDepthAndIndex(ND); | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 805 | } | 
|  | 806 | if (Depth >= TemplateArgs.getNumLevels() || | 
|  | 807 | !TemplateArgs.hasTemplateArgument(Depth, Index)) | 
| Richard Smith | 198223b | 2012-07-18 01:29:05 +0000 | [diff] [blame] | 808 | // The pattern refers to an unknown template argument. We're not ready to | 
|  | 809 | // expand this pack yet. | 
| David Blaikie | 7a30dc5 | 2013-02-21 01:47:18 +0000 | [diff] [blame] | 810 | return None; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 811 |  | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 812 | // Determine the size of the argument pack. | 
| Richard Smith | 198223b | 2012-07-18 01:29:05 +0000 | [diff] [blame] | 813 | unsigned Size = TemplateArgs(Depth, Index).pack_size(); | 
|  | 814 | assert((!Result || *Result == Size) && "inconsistent pack sizes"); | 
|  | 815 | Result = Size; | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 816 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 817 |  | 
| Richard Smith | 198223b | 2012-07-18 01:29:05 +0000 | [diff] [blame] | 818 | return Result; | 
| Douglas Gregor | 5cde386 | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 819 | } | 
|  | 820 |  | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 821 | bool Sema::containsUnexpandedParameterPacks(Declarator &D) { | 
|  | 822 | const DeclSpec &DS = D.getDeclSpec(); | 
|  | 823 | switch (DS.getTypeSpecType()) { | 
| Faisal Vali | 090da2d | 2018-01-01 18:23:28 +0000 | [diff] [blame] | 824 | case TST_typename: | 
|  | 825 | case TST_typeofType: | 
|  | 826 | case TST_underlyingType: | 
|  | 827 | case TST_atomic: { | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 828 | QualType T = DS.getRepAsType().get(); | 
|  | 829 | if (!T.isNull() && T->containsUnexpandedParameterPack()) | 
|  | 830 | return true; | 
|  | 831 | break; | 
|  | 832 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 833 |  | 
| Faisal Vali | 090da2d | 2018-01-01 18:23:28 +0000 | [diff] [blame] | 834 | case TST_typeofExpr: | 
|  | 835 | case TST_decltype: | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 836 | if (DS.getRepAsExpr() && | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 837 | DS.getRepAsExpr()->containsUnexpandedParameterPack()) | 
|  | 838 | return true; | 
|  | 839 | break; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 840 |  | 
| Faisal Vali | 090da2d | 2018-01-01 18:23:28 +0000 | [diff] [blame] | 841 | case TST_unspecified: | 
|  | 842 | case TST_void: | 
|  | 843 | case TST_char: | 
|  | 844 | case TST_wchar: | 
| Richard Smith | 3a8244d | 2018-05-01 05:02:45 +0000 | [diff] [blame] | 845 | case TST_char8: | 
| Faisal Vali | 090da2d | 2018-01-01 18:23:28 +0000 | [diff] [blame] | 846 | case TST_char16: | 
|  | 847 | case TST_char32: | 
|  | 848 | case TST_int: | 
|  | 849 | case TST_int128: | 
|  | 850 | case TST_half: | 
|  | 851 | case TST_float: | 
|  | 852 | case TST_double: | 
| Leonard Chan | f921d85 | 2018-06-04 16:07:52 +0000 | [diff] [blame] | 853 | case TST_Accum: | 
| Leonard Chan | ab80f3c | 2018-06-14 14:53:51 +0000 | [diff] [blame] | 854 | case TST_Fract: | 
| Faisal Vali | 090da2d | 2018-01-01 18:23:28 +0000 | [diff] [blame] | 855 | case TST_Float16: | 
|  | 856 | case TST_float128: | 
|  | 857 | case TST_bool: | 
|  | 858 | case TST_decimal32: | 
|  | 859 | case TST_decimal64: | 
|  | 860 | case TST_decimal128: | 
|  | 861 | case TST_enum: | 
|  | 862 | case TST_union: | 
|  | 863 | case TST_struct: | 
|  | 864 | case TST_interface: | 
|  | 865 | case TST_class: | 
|  | 866 | case TST_auto: | 
|  | 867 | case TST_auto_type: | 
|  | 868 | case TST_decltype_auto: | 
|  | 869 | #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: | 
| Alexey Bader | b62f144 | 2016-04-13 08:33:41 +0000 | [diff] [blame] | 870 | #include "clang/Basic/OpenCLImageTypes.def" | 
| Faisal Vali | 090da2d | 2018-01-01 18:23:28 +0000 | [diff] [blame] | 871 | case TST_unknown_anytype: | 
|  | 872 | case TST_error: | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 873 | break; | 
|  | 874 | } | 
| Larisse Voufo | 2e84650 | 2014-08-29 21:08:16 +0000 | [diff] [blame] | 875 |  | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 876 | for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { | 
|  | 877 | const DeclaratorChunk &Chunk = D.getTypeObject(I); | 
|  | 878 | switch (Chunk.Kind) { | 
|  | 879 | case DeclaratorChunk::Pointer: | 
|  | 880 | case DeclaratorChunk::Reference: | 
|  | 881 | case DeclaratorChunk::Paren: | 
| Xiuli Pan | 9c14e28 | 2016-01-09 12:53:17 +0000 | [diff] [blame] | 882 | case DeclaratorChunk::Pipe: | 
| Larisse Voufo | 2e84650 | 2014-08-29 21:08:16 +0000 | [diff] [blame] | 883 | case DeclaratorChunk::BlockPointer: | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 884 | // These declarator chunks cannot contain any parameter packs. | 
|  | 885 | break; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 886 |  | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 887 | case DeclaratorChunk::Array: | 
| Larisse Voufo | 2e84650 | 2014-08-29 21:08:16 +0000 | [diff] [blame] | 888 | if (Chunk.Arr.NumElts && | 
|  | 889 | Chunk.Arr.NumElts->containsUnexpandedParameterPack()) | 
|  | 890 | return true; | 
|  | 891 | break; | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 892 | case DeclaratorChunk::Function: | 
| Larisse Voufo | 2e84650 | 2014-08-29 21:08:16 +0000 | [diff] [blame] | 893 | for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) { | 
|  | 894 | ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param); | 
|  | 895 | QualType ParamTy = Param->getType(); | 
|  | 896 | assert(!ParamTy.isNull() && "Couldn't parse type?"); | 
|  | 897 | if (ParamTy->containsUnexpandedParameterPack()) return true; | 
|  | 898 | } | 
|  | 899 |  | 
|  | 900 | if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) { | 
| Reid Kleckner | 078aea9 | 2016-12-09 17:14:05 +0000 | [diff] [blame] | 901 | for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) { | 
| Larisse Voufo | 2e84650 | 2014-08-29 21:08:16 +0000 | [diff] [blame] | 902 | if (Chunk.Fun.Exceptions[i] | 
|  | 903 | .Ty.get() | 
|  | 904 | ->containsUnexpandedParameterPack()) | 
|  | 905 | return true; | 
|  | 906 | } | 
| Richard Smith | eaf11ad | 2018-05-03 03:58:32 +0000 | [diff] [blame] | 907 | } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) && | 
| Larisse Voufo | 2e84650 | 2014-08-29 21:08:16 +0000 | [diff] [blame] | 908 | Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack()) | 
|  | 909 | return true; | 
|  | 910 |  | 
| Nico Weber | 8d26b72 | 2014-12-30 02:06:40 +0000 | [diff] [blame] | 911 | if (Chunk.Fun.hasTrailingReturnType()) { | 
|  | 912 | QualType T = Chunk.Fun.getTrailingReturnType().get(); | 
| Fangrui Song | 99337e2 | 2018-07-20 08:19:20 +0000 | [diff] [blame] | 913 | if (!T.isNull() && T->containsUnexpandedParameterPack()) | 
|  | 914 | return true; | 
| Nico Weber | 8d26b72 | 2014-12-30 02:06:40 +0000 | [diff] [blame] | 915 | } | 
| Larisse Voufo | 2e84650 | 2014-08-29 21:08:16 +0000 | [diff] [blame] | 916 | break; | 
|  | 917 |  | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 918 | case DeclaratorChunk::MemberPointer: | 
|  | 919 | if (Chunk.Mem.Scope().getScopeRep() && | 
|  | 920 | Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) | 
|  | 921 | return true; | 
|  | 922 | break; | 
|  | 923 | } | 
|  | 924 | } | 
| Fangrui Song | 99337e2 | 2018-07-20 08:19:20 +0000 | [diff] [blame] | 925 |  | 
| Douglas Gregor | 27b4c16 | 2010-12-23 22:44:42 +0000 | [diff] [blame] | 926 | return false; | 
|  | 927 | } | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 928 |  | 
| Kaelyn Uhrain | 637b5b3 | 2012-01-13 23:10:36 +0000 | [diff] [blame] | 929 | namespace { | 
|  | 930 |  | 
|  | 931 | // Callback to only accept typo corrections that refer to parameter packs. | 
| Bruno Ricci | 70ad396 | 2019-03-25 17:08:51 +0000 | [diff] [blame] | 932 | class ParameterPackValidatorCCC final : public CorrectionCandidateCallback { | 
| Kaelyn Uhrain | 637b5b3 | 2012-01-13 23:10:36 +0000 | [diff] [blame] | 933 | public: | 
| Craig Topper | e14c0f8 | 2014-03-12 04:55:44 +0000 | [diff] [blame] | 934 | bool ValidateCandidate(const TypoCorrection &candidate) override { | 
| Kaelyn Uhrain | 637b5b3 | 2012-01-13 23:10:36 +0000 | [diff] [blame] | 935 | NamedDecl *ND = candidate.getCorrectionDecl(); | 
|  | 936 | return ND && ND->isParameterPack(); | 
|  | 937 | } | 
| Bruno Ricci | 70ad396 | 2019-03-25 17:08:51 +0000 | [diff] [blame] | 938 |  | 
|  | 939 | std::unique_ptr<CorrectionCandidateCallback> clone() override { | 
|  | 940 | return llvm::make_unique<ParameterPackValidatorCCC>(*this); | 
|  | 941 | } | 
| Kaelyn Uhrain | 637b5b3 | 2012-01-13 23:10:36 +0000 | [diff] [blame] | 942 | }; | 
|  | 943 |  | 
| Alexander Kornienko | ab9db51 | 2015-06-22 23:07:51 +0000 | [diff] [blame] | 944 | } | 
| Kaelyn Uhrain | 637b5b3 | 2012-01-13 23:10:36 +0000 | [diff] [blame] | 945 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 946 | /// Called when an expression computing the size of a parameter pack | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 947 | /// is parsed. | 
|  | 948 | /// | 
|  | 949 | /// \code | 
|  | 950 | /// template<typename ...Types> struct count { | 
|  | 951 | ///   static const unsigned value = sizeof...(Types); | 
|  | 952 | /// }; | 
|  | 953 | /// \endcode | 
|  | 954 | /// | 
|  | 955 | // | 
|  | 956 | /// \param OpLoc The location of the "sizeof" keyword. | 
|  | 957 | /// \param Name The name of the parameter pack whose size will be determined. | 
|  | 958 | /// \param NameLoc The source location of the name of the parameter pack. | 
|  | 959 | /// \param RParenLoc The location of the closing parentheses. | 
|  | 960 | ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, | 
|  | 961 | SourceLocation OpLoc, | 
|  | 962 | IdentifierInfo &Name, | 
|  | 963 | SourceLocation NameLoc, | 
|  | 964 | SourceLocation RParenLoc) { | 
|  | 965 | // C++0x [expr.sizeof]p5: | 
|  | 966 | //   The identifier in a sizeof... expression shall name a parameter pack. | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 967 | LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); | 
|  | 968 | LookupName(R, S); | 
| Craig Topper | c3ec149 | 2014-05-26 06:22:03 +0000 | [diff] [blame] | 969 |  | 
|  | 970 | NamedDecl *ParameterPack = nullptr; | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 971 | switch (R.getResultKind()) { | 
|  | 972 | case LookupResult::Found: | 
|  | 973 | ParameterPack = R.getFoundDecl(); | 
|  | 974 | break; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 975 |  | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 976 | case LookupResult::NotFound: | 
| Bruno Ricci | 70ad396 | 2019-03-25 17:08:51 +0000 | [diff] [blame] | 977 | case LookupResult::NotFoundInCurrentInstantiation: { | 
|  | 978 | ParameterPackValidatorCCC CCC{}; | 
| Kaelyn Takata | 89c881b | 2014-10-27 18:07:29 +0000 | [diff] [blame] | 979 | if (TypoCorrection Corrected = | 
|  | 980 | CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, | 
| Bruno Ricci | 70ad396 | 2019-03-25 17:08:51 +0000 | [diff] [blame] | 981 | CCC, CTK_ErrorRecovery)) { | 
| Richard Smith | f9b1510 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 982 | diagnoseTypo(Corrected, | 
|  | 983 | PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, | 
|  | 984 | PDiag(diag::note_parameter_pack_here)); | 
| Kaelyn Uhrain | 637b5b3 | 2012-01-13 23:10:36 +0000 | [diff] [blame] | 985 | ParameterPack = Corrected.getCorrectionDecl(); | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 986 | } | 
| Reid Kleckner | 4dc0b1a | 2018-11-01 19:54:45 +0000 | [diff] [blame] | 987 | break; | 
| Bruno Ricci | 70ad396 | 2019-03-25 17:08:51 +0000 | [diff] [blame] | 988 | } | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 989 | case LookupResult::FoundOverloaded: | 
|  | 990 | case LookupResult::FoundUnresolvedValue: | 
|  | 991 | break; | 
| Fangrui Song | 99337e2 | 2018-07-20 08:19:20 +0000 | [diff] [blame] | 992 |  | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 993 | case LookupResult::Ambiguous: | 
|  | 994 | DiagnoseAmbiguousLookup(R); | 
|  | 995 | return ExprError(); | 
|  | 996 | } | 
| Fangrui Song | 99337e2 | 2018-07-20 08:19:20 +0000 | [diff] [blame] | 997 |  | 
| Douglas Gregor | 3c6bd2a | 2011-01-05 21:11:38 +0000 | [diff] [blame] | 998 | if (!ParameterPack || !ParameterPack->isParameterPack()) { | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 999 | Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) | 
|  | 1000 | << &Name; | 
|  | 1001 | return ExprError(); | 
|  | 1002 | } | 
|  | 1003 |  | 
| Nick Lewycky | 45b5052 | 2013-02-02 00:25:55 +0000 | [diff] [blame] | 1004 | MarkAnyDeclReferenced(OpLoc, ParameterPack, true); | 
| Eli Friedman | 23b1be9 | 2012-03-01 21:32:56 +0000 | [diff] [blame] | 1005 |  | 
| Richard Smith | d784e68 | 2015-09-23 21:41:42 +0000 | [diff] [blame] | 1006 | return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc, | 
|  | 1007 | RParenLoc); | 
| Douglas Gregor | 820ba7b | 2011-01-04 17:33:58 +0000 | [diff] [blame] | 1008 | } | 
| Eli Friedman | 94e9eaa | 2013-06-20 04:11:21 +0000 | [diff] [blame] | 1009 |  | 
|  | 1010 | TemplateArgumentLoc | 
|  | 1011 | Sema::getTemplateArgumentPackExpansionPattern( | 
|  | 1012 | TemplateArgumentLoc OrigLoc, | 
|  | 1013 | SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const { | 
|  | 1014 | const TemplateArgument &Argument = OrigLoc.getArgument(); | 
|  | 1015 | assert(Argument.isPackExpansion()); | 
|  | 1016 | switch (Argument.getKind()) { | 
|  | 1017 | case TemplateArgument::Type: { | 
|  | 1018 | // FIXME: We shouldn't ever have to worry about missing | 
|  | 1019 | // type-source info! | 
|  | 1020 | TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo(); | 
|  | 1021 | if (!ExpansionTSInfo) | 
|  | 1022 | ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(), | 
|  | 1023 | Ellipsis); | 
|  | 1024 | PackExpansionTypeLoc Expansion = | 
|  | 1025 | ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>(); | 
|  | 1026 | Ellipsis = Expansion.getEllipsisLoc(); | 
|  | 1027 |  | 
|  | 1028 | TypeLoc Pattern = Expansion.getPatternLoc(); | 
|  | 1029 | NumExpansions = Expansion.getTypePtr()->getNumExpansions(); | 
|  | 1030 |  | 
|  | 1031 | // We need to copy the TypeLoc because TemplateArgumentLocs store a | 
|  | 1032 | // TypeSourceInfo. | 
|  | 1033 | // FIXME: Find some way to avoid the copy? | 
|  | 1034 | TypeLocBuilder TLB; | 
|  | 1035 | TLB.pushFullCopy(Pattern); | 
|  | 1036 | TypeSourceInfo *PatternTSInfo = | 
|  | 1037 | TLB.getTypeSourceInfo(Context, Pattern.getType()); | 
|  | 1038 | return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), | 
|  | 1039 | PatternTSInfo); | 
|  | 1040 | } | 
|  | 1041 |  | 
|  | 1042 | case TemplateArgument::Expression: { | 
|  | 1043 | PackExpansionExpr *Expansion | 
|  | 1044 | = cast<PackExpansionExpr>(Argument.getAsExpr()); | 
|  | 1045 | Expr *Pattern = Expansion->getPattern(); | 
|  | 1046 | Ellipsis = Expansion->getEllipsisLoc(); | 
|  | 1047 | NumExpansions = Expansion->getNumExpansions(); | 
|  | 1048 | return TemplateArgumentLoc(Pattern, Pattern); | 
|  | 1049 | } | 
|  | 1050 |  | 
|  | 1051 | case TemplateArgument::TemplateExpansion: | 
|  | 1052 | Ellipsis = OrigLoc.getTemplateEllipsisLoc(); | 
|  | 1053 | NumExpansions = Argument.getNumTemplateExpansions(); | 
|  | 1054 | return TemplateArgumentLoc(Argument.getPackExpansionPattern(), | 
|  | 1055 | OrigLoc.getTemplateQualifierLoc(), | 
|  | 1056 | OrigLoc.getTemplateNameLoc()); | 
|  | 1057 |  | 
|  | 1058 | case TemplateArgument::Declaration: | 
|  | 1059 | case TemplateArgument::NullPtr: | 
|  | 1060 | case TemplateArgument::Template: | 
|  | 1061 | case TemplateArgument::Integral: | 
|  | 1062 | case TemplateArgument::Pack: | 
|  | 1063 | case TemplateArgument::Null: | 
|  | 1064 | return TemplateArgumentLoc(); | 
|  | 1065 | } | 
|  | 1066 |  | 
|  | 1067 | llvm_unreachable("Invalid TemplateArgument Kind!"); | 
|  | 1068 | } | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1069 |  | 
| Richard Smith | c5452ed | 2016-10-19 22:18:42 +0000 | [diff] [blame] | 1070 | Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) { | 
|  | 1071 | assert(Arg.containsUnexpandedParameterPack()); | 
|  | 1072 |  | 
|  | 1073 | // If this is a substituted pack, grab that pack. If not, we don't know | 
|  | 1074 | // the size yet. | 
|  | 1075 | // FIXME: We could find a size in more cases by looking for a substituted | 
|  | 1076 | // pack anywhere within this argument, but that's not necessary in the common | 
|  | 1077 | // case for 'sizeof...(A)' handling. | 
|  | 1078 | TemplateArgument Pack; | 
|  | 1079 | switch (Arg.getKind()) { | 
|  | 1080 | case TemplateArgument::Type: | 
|  | 1081 | if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) | 
|  | 1082 | Pack = Subst->getArgumentPack(); | 
|  | 1083 | else | 
|  | 1084 | return None; | 
|  | 1085 | break; | 
|  | 1086 |  | 
|  | 1087 | case TemplateArgument::Expression: | 
|  | 1088 | if (auto *Subst = | 
|  | 1089 | dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr())) | 
|  | 1090 | Pack = Subst->getArgumentPack(); | 
|  | 1091 | else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr()))  { | 
| Richard Smith | b2997f5 | 2019-05-21 20:10:50 +0000 | [diff] [blame] | 1092 | for (VarDecl *PD : *Subst) | 
| Richard Smith | c5452ed | 2016-10-19 22:18:42 +0000 | [diff] [blame] | 1093 | if (PD->isParameterPack()) | 
|  | 1094 | return None; | 
|  | 1095 | return Subst->getNumExpansions(); | 
|  | 1096 | } else | 
|  | 1097 | return None; | 
|  | 1098 | break; | 
|  | 1099 |  | 
|  | 1100 | case TemplateArgument::Template: | 
|  | 1101 | if (SubstTemplateTemplateParmPackStorage *Subst = | 
|  | 1102 | Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) | 
|  | 1103 | Pack = Subst->getArgumentPack(); | 
|  | 1104 | else | 
|  | 1105 | return None; | 
|  | 1106 | break; | 
|  | 1107 |  | 
|  | 1108 | case TemplateArgument::Declaration: | 
|  | 1109 | case TemplateArgument::NullPtr: | 
|  | 1110 | case TemplateArgument::TemplateExpansion: | 
|  | 1111 | case TemplateArgument::Integral: | 
|  | 1112 | case TemplateArgument::Pack: | 
|  | 1113 | case TemplateArgument::Null: | 
|  | 1114 | return None; | 
|  | 1115 | } | 
|  | 1116 |  | 
|  | 1117 | // Check that no argument in the pack is itself a pack expansion. | 
|  | 1118 | for (TemplateArgument Elem : Pack.pack_elements()) { | 
|  | 1119 | // There's no point recursing in this case; we would have already | 
|  | 1120 | // expanded this pack expansion into the enclosing pack if we could. | 
|  | 1121 | if (Elem.isPackExpansion()) | 
|  | 1122 | return None; | 
|  | 1123 | } | 
|  | 1124 | return Pack.pack_size(); | 
|  | 1125 | } | 
|  | 1126 |  | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1127 | static void CheckFoldOperand(Sema &S, Expr *E) { | 
|  | 1128 | if (!E) | 
|  | 1129 | return; | 
|  | 1130 |  | 
|  | 1131 | E = E->IgnoreImpCasts(); | 
| Richard Smith | 6609443 | 2016-10-20 00:55:15 +0000 | [diff] [blame] | 1132 | auto *OCE = dyn_cast<CXXOperatorCallExpr>(E); | 
|  | 1133 | if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) || | 
|  | 1134 | isa<AbstractConditionalOperator>(E)) { | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1135 | S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand) | 
|  | 1136 | << E->getSourceRange() | 
| Stephen Kelly | f2ceec4 | 2018-08-09 21:08:08 +0000 | [diff] [blame] | 1137 | << FixItHint::CreateInsertion(E->getBeginLoc(), "(") | 
| Stephen Kelly | 1c301dc | 2018-08-09 21:09:38 +0000 | [diff] [blame] | 1138 | << FixItHint::CreateInsertion(E->getEndLoc(), ")"); | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1139 | } | 
|  | 1140 | } | 
|  | 1141 |  | 
|  | 1142 | ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, | 
|  | 1143 | tok::TokenKind Operator, | 
|  | 1144 | SourceLocation EllipsisLoc, Expr *RHS, | 
|  | 1145 | SourceLocation RParenLoc) { | 
|  | 1146 | // LHS and RHS must be cast-expressions. We allow an arbitrary expression | 
|  | 1147 | // in the parser and reduce down to just cast-expressions here. | 
|  | 1148 | CheckFoldOperand(*this, LHS); | 
|  | 1149 | CheckFoldOperand(*this, RHS); | 
|  | 1150 |  | 
| Richard Smith | 90e043d | 2017-02-15 19:57:10 +0000 | [diff] [blame] | 1151 | auto DiscardOperands = [&] { | 
|  | 1152 | CorrectDelayedTyposInExpr(LHS); | 
|  | 1153 | CorrectDelayedTyposInExpr(RHS); | 
|  | 1154 | }; | 
|  | 1155 |  | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1156 | // [expr.prim.fold]p3: | 
|  | 1157 | //   In a binary fold, op1 and op2 shall be the same fold-operator, and | 
|  | 1158 | //   either e1 shall contain an unexpanded parameter pack or e2 shall contain | 
|  | 1159 | //   an unexpanded parameter pack, but not both. | 
|  | 1160 | if (LHS && RHS && | 
|  | 1161 | LHS->containsUnexpandedParameterPack() == | 
|  | 1162 | RHS->containsUnexpandedParameterPack()) { | 
| Richard Smith | 90e043d | 2017-02-15 19:57:10 +0000 | [diff] [blame] | 1163 | DiscardOperands(); | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1164 | return Diag(EllipsisLoc, | 
|  | 1165 | LHS->containsUnexpandedParameterPack() | 
|  | 1166 | ? diag::err_fold_expression_packs_both_sides | 
|  | 1167 | : diag::err_pack_expansion_without_parameter_packs) | 
|  | 1168 | << LHS->getSourceRange() << RHS->getSourceRange(); | 
|  | 1169 | } | 
|  | 1170 |  | 
|  | 1171 | // [expr.prim.fold]p2: | 
|  | 1172 | //   In a unary fold, the cast-expression shall contain an unexpanded | 
|  | 1173 | //   parameter pack. | 
|  | 1174 | if (!LHS || !RHS) { | 
|  | 1175 | Expr *Pack = LHS ? LHS : RHS; | 
|  | 1176 | assert(Pack && "fold expression with neither LHS nor RHS"); | 
| Richard Smith | 90e043d | 2017-02-15 19:57:10 +0000 | [diff] [blame] | 1177 | DiscardOperands(); | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1178 | if (!Pack->containsUnexpandedParameterPack()) | 
|  | 1179 | return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | 
|  | 1180 | << Pack->getSourceRange(); | 
|  | 1181 | } | 
|  | 1182 |  | 
|  | 1183 | BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator); | 
| Richard Smith | c7214f6 | 2019-05-13 08:31:14 +0000 | [diff] [blame] | 1184 | return BuildCXXFoldExpr(LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc, | 
|  | 1185 | None); | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1186 | } | 
|  | 1187 |  | 
|  | 1188 | ExprResult Sema::BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, | 
|  | 1189 | BinaryOperatorKind Operator, | 
|  | 1190 | SourceLocation EllipsisLoc, Expr *RHS, | 
| Richard Smith | c7214f6 | 2019-05-13 08:31:14 +0000 | [diff] [blame] | 1191 | SourceLocation RParenLoc, | 
|  | 1192 | Optional<unsigned> NumExpansions) { | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1193 | return new (Context) CXXFoldExpr(Context.DependentTy, LParenLoc, LHS, | 
| Richard Smith | c7214f6 | 2019-05-13 08:31:14 +0000 | [diff] [blame] | 1194 | Operator, EllipsisLoc, RHS, RParenLoc, | 
|  | 1195 | NumExpansions); | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1196 | } | 
|  | 1197 |  | 
|  | 1198 | ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, | 
|  | 1199 | BinaryOperatorKind Operator) { | 
|  | 1200 | // [temp.variadic]p9: | 
|  | 1201 | //   If N is zero for a unary fold-expression, the value of the expression is | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1202 | //       &&  ->  true | 
|  | 1203 | //       ||  ->  false | 
|  | 1204 | //       ,   ->  void() | 
|  | 1205 | //   if the operator is not listed [above], the instantiation is ill-formed. | 
|  | 1206 | // | 
|  | 1207 | // Note that we need to use something like int() here, not merely 0, to | 
|  | 1208 | // prevent the result from being a null pointer constant. | 
|  | 1209 | QualType ScalarType; | 
|  | 1210 | switch (Operator) { | 
| Richard Smith | 0f0af19 | 2014-11-08 05:07:16 +0000 | [diff] [blame] | 1211 | case BO_LOr: | 
|  | 1212 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false); | 
|  | 1213 | case BO_LAnd: | 
|  | 1214 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true); | 
|  | 1215 | case BO_Comma: | 
|  | 1216 | ScalarType = Context.VoidTy; | 
|  | 1217 | break; | 
|  | 1218 |  | 
|  | 1219 | default: | 
|  | 1220 | return Diag(EllipsisLoc, diag::err_fold_expression_empty) | 
|  | 1221 | << BinaryOperator::getOpcodeStr(Operator); | 
|  | 1222 | } | 
|  | 1223 |  | 
|  | 1224 | return new (Context) CXXScalarValueInitExpr( | 
|  | 1225 | ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc), | 
|  | 1226 | EllipsisLoc); | 
|  | 1227 | } |