clang 17.0.0git
SemaTemplateVariadic.cpp
Go to the documentation of this file.
1//===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
2//
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
6//===----------------------------------------------------------------------===/
7//
8// This file implements semantic analysis for C++0x variadic templates.
9//===----------------------------------------------------------------------===/
10
11#include "clang/Sema/Sema.h"
12#include "TypeLocBuilder.h"
13#include "clang/AST/Expr.h"
15#include "clang/AST/TypeLoc.h"
16#include "clang/Sema/Lookup.h"
20#include "clang/Sema/Template.h"
21#include <optional>
22
23using namespace clang;
24
25//----------------------------------------------------------------------------
26// Visitor that collects unexpanded parameter packs
27//----------------------------------------------------------------------------
28
29namespace {
30 /// A class that collects unexpanded parameter packs.
31 class CollectUnexpandedParameterPacksVisitor :
32 public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
33 {
35 inherited;
36
38
39 bool InLambda = false;
40 unsigned DepthLimit = (unsigned)-1;
41
42 void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
43 if (auto *VD = dyn_cast<VarDecl>(ND)) {
44 // For now, the only problematic case is a generic lambda's templated
45 // call operator, so we don't need to look for all the other ways we
46 // could have reached a dependent parameter pack.
47 auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
48 auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
49 if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
50 return;
51 } else if (getDepthAndIndex(ND).first >= DepthLimit)
52 return;
53
54 Unexpanded.push_back({ND, Loc});
55 }
56 void addUnexpanded(const TemplateTypeParmType *T,
58 if (T->getDepth() < DepthLimit)
59 Unexpanded.push_back({T, Loc});
60 }
61
62 public:
63 explicit CollectUnexpandedParameterPacksVisitor(
65 : Unexpanded(Unexpanded) {}
66
67 bool shouldWalkTypesOfTypeLocs() const { return false; }
68
69 //------------------------------------------------------------------------
70 // Recording occurrences of (unexpanded) parameter packs.
71 //------------------------------------------------------------------------
72
73 /// Record occurrences of template type parameter packs.
74 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
75 if (TL.getTypePtr()->isParameterPack())
76 addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
77 return true;
78 }
79
80 /// Record occurrences of template type parameter packs
81 /// when we don't have proper source-location information for
82 /// them.
83 ///
84 /// Ideally, this routine would never be used.
85 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
86 if (T->isParameterPack())
87 addUnexpanded(T);
88
89 return true;
90 }
91
92 /// Record occurrences of function and non-type template
93 /// parameter packs in an expression.
94 bool VisitDeclRefExpr(DeclRefExpr *E) {
95 if (E->getDecl()->isParameterPack())
96 addUnexpanded(E->getDecl(), E->getLocation());
97
98 return true;
99 }
100
101 /// Record occurrences of template template parameter packs.
102 bool TraverseTemplateName(TemplateName Template) {
103 if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
104 Template.getAsTemplateDecl())) {
105 if (TTP->isParameterPack())
106 addUnexpanded(TTP);
107 }
108
109 return inherited::TraverseTemplateName(Template);
110 }
111
112 /// Suppress traversal into Objective-C container literal
113 /// elements that are pack expansions.
114 bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
116 return true;
117
118 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
120 if (Element.isPackExpansion())
121 continue;
122
123 TraverseStmt(Element.Key);
124 TraverseStmt(Element.Value);
125 }
126 return true;
127 }
128 //------------------------------------------------------------------------
129 // Pruning the search for unexpanded parameter packs.
130 //------------------------------------------------------------------------
131
132 /// Suppress traversal into statements and expressions that
133 /// do not contain unexpanded parameter packs.
134 bool TraverseStmt(Stmt *S) {
135 Expr *E = dyn_cast_or_null<Expr>(S);
136 if ((E && E->containsUnexpandedParameterPack()) || InLambda)
137 return inherited::TraverseStmt(S);
138
139 return true;
140 }
141
142 /// Suppress traversal into types that do not contain
143 /// unexpanded parameter packs.
144 bool TraverseType(QualType T) {
145 if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
146 return inherited::TraverseType(T);
147
148 return true;
149 }
150
151 /// Suppress traversal into types with location information
152 /// that do not contain unexpanded parameter packs.
153 bool TraverseTypeLoc(TypeLoc TL) {
154 if ((!TL.getType().isNull() &&
156 InLambda)
158
159 return true;
160 }
161
162 /// Suppress traversal of parameter packs.
163 bool TraverseDecl(Decl *D) {
164 // A function parameter pack is a pack expansion, so cannot contain
165 // an unexpanded parameter pack. Likewise for a template parameter
166 // pack that contains any references to other packs.
167 if (D && D->isParameterPack())
168 return true;
169
170 return inherited::TraverseDecl(D);
171 }
172
173 /// Suppress traversal of pack-expanded attributes.
174 bool TraverseAttr(Attr *A) {
175 if (A->isPackExpansion())
176 return true;
177
178 return inherited::TraverseAttr(A);
179 }
180
181 /// Suppress traversal of pack expansion expressions and types.
182 ///@{
183 bool TraversePackExpansionType(PackExpansionType *T) { return true; }
184 bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
185 bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
186 bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
187
188 ///@}
189
190 /// Suppress traversal of using-declaration pack expansion.
191 bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
192 if (D->isPackExpansion())
193 return true;
194
195 return inherited::TraverseUnresolvedUsingValueDecl(D);
196 }
197
198 /// Suppress traversal of using-declaration pack expansion.
199 bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
200 if (D->isPackExpansion())
201 return true;
202
203 return inherited::TraverseUnresolvedUsingTypenameDecl(D);
204 }
205
206 /// Suppress traversal of template argument pack expansions.
208 if (Arg.isPackExpansion())
209 return true;
210
212 }
213
214 /// Suppress traversal of template argument pack expansions.
216 if (ArgLoc.getArgument().isPackExpansion())
217 return true;
218
220 }
221
222 /// Suppress traversal of base specifier pack expansions.
224 if (Base.isPackExpansion())
225 return true;
226
228 }
229
230 /// Suppress traversal of mem-initializer pack expansions.
232 if (Init->isPackExpansion())
233 return true;
234
236 }
237
238 /// Note whether we're traversing a lambda containing an unexpanded
239 /// parameter pack. In this case, the unexpanded pack can occur anywhere,
240 /// including all the places where we normally wouldn't look. Within a
241 /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
242 /// outside an expression.
243 bool TraverseLambdaExpr(LambdaExpr *Lambda) {
244 // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
245 // even if it's contained within another lambda.
246 if (!Lambda->containsUnexpandedParameterPack())
247 return true;
248
249 bool WasInLambda = InLambda;
250 unsigned OldDepthLimit = DepthLimit;
251
252 InLambda = true;
253 if (auto *TPL = Lambda->getTemplateParameterList())
254 DepthLimit = TPL->getDepth();
255
256 inherited::TraverseLambdaExpr(Lambda);
257
258 InLambda = WasInLambda;
259 DepthLimit = OldDepthLimit;
260 return true;
261 }
262
263 /// Suppress traversal within pack expansions in lambda captures.
264 bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
265 Expr *Init) {
266 if (C->isPackExpansion())
267 return true;
268
269 return inherited::TraverseLambdaCapture(Lambda, C, Init);
270 }
271 };
272}
273
274/// Determine whether it's possible for an unexpanded parameter pack to
275/// be valid in this location. This only happens when we're in a declaration
276/// that is nested within an expression that could be expanded, such as a
277/// lambda-expression within a function call.
278///
279/// This is conservatively correct, but may claim that some unexpanded packs are
280/// permitted when they are not.
282 for (auto *SI : FunctionScopes)
283 if (isa<sema::LambdaScopeInfo>(SI))
284 return true;
285 return false;
286}
287
288/// Diagnose all of the unexpanded parameter packs in the given
289/// vector.
290bool
294 if (Unexpanded.empty())
295 return false;
296
297 // If we are within a lambda expression and referencing a pack that is not
298 // declared within the lambda itself, that lambda contains an unexpanded
299 // parameter pack, and we are done.
300 // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
301 // later.
302 SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences;
303 if (auto *LSI = getEnclosingLambda()) {
304 for (auto &Pack : Unexpanded) {
305 auto DeclaresThisPack = [&](NamedDecl *LocalPack) {
306 if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) {
307 auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
308 return TTPD && TTPD->getTypeForDecl() == TTPT;
309 }
310 return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
311 };
312 if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack))
313 LambdaParamPackReferences.push_back(Pack);
314 }
315
316 if (LambdaParamPackReferences.empty()) {
317 // Construct in lambda only references packs declared outside the lambda.
318 // That's OK for now, but the lambda itself is considered to contain an
319 // unexpanded pack in this case, which will require expansion outside the
320 // lambda.
321
322 // We do not permit pack expansion that would duplicate a statement
323 // expression, not even within a lambda.
324 // FIXME: We could probably support this for statement expressions that
325 // do not contain labels.
326 // FIXME: This is insufficient to detect this problem; consider
327 // f( ({ bad: 0; }) + pack ... );
328 bool EnclosingStmtExpr = false;
329 for (unsigned N = FunctionScopes.size(); N; --N) {
331 if (llvm::any_of(
332 Func->CompoundScopes,
333 [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) {
334 EnclosingStmtExpr = true;
335 break;
336 }
337 // Coumpound-statements outside the lambda are OK for now; we'll check
338 // for those when we finish handling the lambda.
339 if (Func == LSI)
340 break;
341 }
342
343 if (!EnclosingStmtExpr) {
344 LSI->ContainsUnexpandedParameterPack = true;
345 return false;
346 }
347 } else {
348 Unexpanded = LambdaParamPackReferences;
349 }
350 }
351
355
356 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
357 IdentifierInfo *Name = nullptr;
358 if (const TemplateTypeParmType *TTP
359 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
360 Name = TTP->getIdentifier();
361 else
362 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
363
364 if (Name && NamesKnown.insert(Name).second)
365 Names.push_back(Name);
366
367 if (Unexpanded[I].second.isValid())
368 Locations.push_back(Unexpanded[I].second);
369 }
370
371 auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
372 << (int)UPPC << (int)Names.size();
373 for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
374 DB << Names[I];
375
376 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
377 DB << SourceRange(Locations[I]);
378 return true;
379}
380
384 // C++0x [temp.variadic]p5:
385 // An appearance of a name of a parameter pack that is not expanded is
386 // ill-formed.
388 return false;
389
391 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
392 T->getTypeLoc());
393 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
394 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
395}
396
399 // C++0x [temp.variadic]p5:
400 // An appearance of a name of a parameter pack that is not expanded is
401 // ill-formed.
403 return false;
404
406 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
407 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
408 return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
409}
410
413 return false;
414
416 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
417 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
418
419 // We only care about unexpanded references to the RequiresExpr's own
420 // parameter packs.
421 auto Parms = RE->getLocalParameters();
422 llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
424 for (auto Parm : Unexpanded)
425 if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl *>()))
426 UnexpandedParms.push_back(Parm);
427 if (UnexpandedParms.empty())
428 return false;
429
431 UnexpandedParms);
432}
433
436 // C++0x [temp.variadic]p5:
437 // An appearance of a name of a parameter pack that is not expanded is
438 // ill-formed.
439 if (!SS.getScopeRep() ||
441 return false;
442
444 CollectUnexpandedParameterPacksVisitor(Unexpanded)
445 .TraverseNestedNameSpecifier(SS.getScopeRep());
446 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
448 UPPC, Unexpanded);
449}
450
453 // C++0x [temp.variadic]p5:
454 // An appearance of a name of a parameter pack that is not expanded is
455 // ill-formed.
456 switch (NameInfo.getName().getNameKind()) {
465 return false;
466
470 // FIXME: We shouldn't need this null check!
471 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
472 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
473
475 return false;
476
477 break;
478 }
479
481 CollectUnexpandedParameterPacksVisitor(Unexpanded)
482 .TraverseType(NameInfo.getName().getCXXNameType());
483 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
484 return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
485}
486
488 TemplateName Template,
490
491 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
492 return false;
493
495 CollectUnexpandedParameterPacksVisitor(Unexpanded)
496 .TraverseTemplateName(Template);
497 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
498 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
499}
500
503 if (Arg.getArgument().isNull() ||
505 return false;
506
508 CollectUnexpandedParameterPacksVisitor(Unexpanded)
509 .TraverseTemplateArgumentLoc(Arg);
510 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
511 return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
512}
513
516 CollectUnexpandedParameterPacksVisitor(Unexpanded)
517 .TraverseTemplateArgument(Arg);
518}
519
522 CollectUnexpandedParameterPacksVisitor(Unexpanded)
523 .TraverseTemplateArgumentLoc(Arg);
524}
525
528 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
529}
530
533 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
534}
535
539 CollectUnexpandedParameterPacksVisitor(Unexpanded)
540 .TraverseNestedNameSpecifierLoc(NNS);
541}
542
544 const DeclarationNameInfo &NameInfo,
546 CollectUnexpandedParameterPacksVisitor(Unexpanded)
547 .TraverseDeclarationNameInfo(NameInfo);
548}
549
550
553 SourceLocation EllipsisLoc) {
554 if (Arg.isInvalid())
555 return Arg;
556
557 switch (Arg.getKind()) {
559 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
560 if (Result.isInvalid())
561 return ParsedTemplateArgument();
562
563 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
564 Arg.getLocation());
565 }
566
568 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
569 if (Result.isInvalid())
570 return ParsedTemplateArgument();
571
572 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
573 Arg.getLocation());
574 }
575
578 SourceRange R(Arg.getLocation());
579 if (Arg.getScopeSpec().isValid())
581 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
582 << R;
583 return ParsedTemplateArgument();
584 }
585
586 return Arg.getTemplatePackExpansion(EllipsisLoc);
587 }
588 llvm_unreachable("Unhandled template argument kind?");
589}
590
592 SourceLocation EllipsisLoc) {
593 TypeSourceInfo *TSInfo;
594 GetTypeFromParser(Type, &TSInfo);
595 if (!TSInfo)
596 return true;
597
598 TypeSourceInfo *TSResult =
599 CheckPackExpansion(TSInfo, EllipsisLoc, std::nullopt);
600 if (!TSResult)
601 return true;
602
603 return CreateParsedType(TSResult->getType(), TSResult);
604}
605
608 std::optional<unsigned> NumExpansions) {
609 // Create the pack expansion type and source-location information.
611 Pattern->getTypeLoc().getSourceRange(),
612 EllipsisLoc, NumExpansions);
613 if (Result.isNull())
614 return nullptr;
615
616 TypeLocBuilder TLB;
617 TLB.pushFullCopy(Pattern->getTypeLoc());
619 TL.setEllipsisLoc(EllipsisLoc);
620
621 return TLB.getTypeSourceInfo(Context, Result);
622}
623
625 SourceLocation EllipsisLoc,
626 std::optional<unsigned> NumExpansions) {
627 // C++11 [temp.variadic]p5:
628 // The pattern of a pack expansion shall name one or more
629 // parameter packs that are not expanded by a nested pack
630 // expansion.
631 //
632 // A pattern containing a deduced type can't occur "naturally" but arises in
633 // the desugaring of an init-capture pack.
634 if (!Pattern->containsUnexpandedParameterPack() &&
635 !Pattern->getContainedDeducedType()) {
636 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
637 << PatternRange;
638 return QualType();
639 }
640
641 return Context.getPackExpansionType(Pattern, NumExpansions,
642 /*ExpectPackInType=*/false);
643}
644
646 return CheckPackExpansion(Pattern, EllipsisLoc, std::nullopt);
647}
648
650 std::optional<unsigned> NumExpansions) {
651 if (!Pattern)
652 return ExprError();
653
654 // C++0x [temp.variadic]p5:
655 // The pattern of a pack expansion shall name one or more
656 // parameter packs that are not expanded by a nested pack
657 // expansion.
658 if (!Pattern->containsUnexpandedParameterPack()) {
659 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
660 << Pattern->getSourceRange();
662 return ExprError();
663 }
664
665 // Create the pack expansion expression and source-location information.
666 return new (Context)
667 PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
668}
669
671 SourceLocation EllipsisLoc, SourceRange PatternRange,
673 const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
674 bool &RetainExpansion, std::optional<unsigned> &NumExpansions) {
675 ShouldExpand = true;
676 RetainExpansion = false;
677 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
678 bool HaveFirstPack = false;
679 std::optional<unsigned> NumPartialExpansions;
680 SourceLocation PartiallySubstitutedPackLoc;
681
682 for (UnexpandedParameterPack ParmPack : Unexpanded) {
683 // Compute the depth and index for this parameter pack.
684 unsigned Depth = 0, Index = 0;
685 IdentifierInfo *Name;
686 bool IsVarDeclPack = false;
687
688 if (const TemplateTypeParmType *TTP =
689 ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
690 Depth = TTP->getDepth();
691 Index = TTP->getIndex();
692 Name = TTP->getIdentifier();
693 } else {
694 NamedDecl *ND = ParmPack.first.get<NamedDecl *>();
695 if (isa<VarDecl>(ND))
696 IsVarDeclPack = true;
697 else
698 std::tie(Depth, Index) = getDepthAndIndex(ND);
699
700 Name = ND->getIdentifier();
701 }
702
703 // Determine the size of this argument pack.
704 unsigned NewPackSize;
705 if (IsVarDeclPack) {
706 // Figure out whether we're instantiating to an argument pack or not.
707 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
708
709 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
711 ParmPack.first.get<NamedDecl *>());
712 if (Instantiation->is<DeclArgumentPack *>()) {
713 // We could expand this function parameter pack.
714 NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
715 } else {
716 // We can't expand this function parameter pack, so we can't expand
717 // the pack expansion.
718 ShouldExpand = false;
719 continue;
720 }
721 } else {
722 // If we don't have a template argument at this depth/index, then we
723 // cannot expand the pack expansion. Make a note of this, but we still
724 // want to check any parameter packs we *do* have arguments for.
725 if (Depth >= TemplateArgs.getNumLevels() ||
726 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
727 ShouldExpand = false;
728 continue;
729 }
730
731 // Determine the size of the argument pack.
732 NewPackSize = TemplateArgs(Depth, Index).pack_size();
733 }
734
735 // C++0x [temp.arg.explicit]p9:
736 // Template argument deduction can extend the sequence of template
737 // arguments corresponding to a template parameter pack, even when the
738 // sequence contains explicitly specified template arguments.
739 if (!IsVarDeclPack && CurrentInstantiationScope) {
740 if (NamedDecl *PartialPack =
742 unsigned PartialDepth, PartialIndex;
743 std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
744 if (PartialDepth == Depth && PartialIndex == Index) {
745 RetainExpansion = true;
746 // We don't actually know the new pack size yet.
747 NumPartialExpansions = NewPackSize;
748 PartiallySubstitutedPackLoc = ParmPack.second;
749 continue;
750 }
751 }
752 }
753
754 if (!NumExpansions) {
755 // The is the first pack we've seen for which we have an argument.
756 // Record it.
757 NumExpansions = NewPackSize;
758 FirstPack.first = Name;
759 FirstPack.second = ParmPack.second;
760 HaveFirstPack = true;
761 continue;
762 }
763
764 if (NewPackSize != *NumExpansions) {
765 // C++0x [temp.variadic]p5:
766 // All of the parameter packs expanded by a pack expansion shall have
767 // the same number of arguments specified.
768 if (HaveFirstPack)
769 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
770 << FirstPack.first << Name << *NumExpansions << NewPackSize
771 << SourceRange(FirstPack.second) << SourceRange(ParmPack.second);
772 else
773 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
774 << Name << *NumExpansions << NewPackSize
775 << SourceRange(ParmPack.second);
776 return true;
777 }
778 }
779
780 // If we're performing a partial expansion but we also have a full expansion,
781 // expand to the number of common arguments. For example, given:
782 //
783 // template<typename ...T> struct A {
784 // template<typename ...U> void f(pair<T, U>...);
785 // };
786 //
787 // ... a call to 'A<int, int>().f<int>' should expand the pack once and
788 // retain an expansion.
789 if (NumPartialExpansions) {
790 if (NumExpansions && *NumExpansions < *NumPartialExpansions) {
791 NamedDecl *PartialPack =
793 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)
794 << PartialPack << *NumPartialExpansions << *NumExpansions
795 << SourceRange(PartiallySubstitutedPackLoc);
796 return true;
797 }
798
799 NumExpansions = NumPartialExpansions;
800 }
801
802 return false;
803}
804
805std::optional<unsigned> Sema::getNumArgumentsInExpansion(
806 QualType T, const MultiLevelTemplateArgumentList &TemplateArgs) {
807 QualType Pattern = cast<PackExpansionType>(T)->getPattern();
809 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
810
811 std::optional<unsigned> Result;
812 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
813 // Compute the depth and index for this parameter pack.
814 unsigned Depth;
815 unsigned Index;
816
817 if (const TemplateTypeParmType *TTP =
818 Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
819 Depth = TTP->getDepth();
820 Index = TTP->getIndex();
821 } else {
822 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
823 if (isa<VarDecl>(ND)) {
824 // Function parameter pack or init-capture pack.
825 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
826
827 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
829 Unexpanded[I].first.get<NamedDecl *>());
830 if (Instantiation->is<Decl *>())
831 // The pattern refers to an unexpanded pack. We're not ready to expand
832 // this pack yet.
833 return std::nullopt;
834
835 unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
836 assert((!Result || *Result == Size) && "inconsistent pack sizes");
837 Result = Size;
838 continue;
839 }
840
841 std::tie(Depth, Index) = getDepthAndIndex(ND);
842 }
843 if (Depth >= TemplateArgs.getNumLevels() ||
844 !TemplateArgs.hasTemplateArgument(Depth, Index))
845 // The pattern refers to an unknown template argument. We're not ready to
846 // expand this pack yet.
847 return std::nullopt;
848
849 // Determine the size of the argument pack.
850 unsigned Size = TemplateArgs(Depth, Index).pack_size();
851 assert((!Result || *Result == Size) && "inconsistent pack sizes");
852 Result = Size;
853 }
854
855 return Result;
856}
857
859 const DeclSpec &DS = D.getDeclSpec();
860 switch (DS.getTypeSpecType()) {
861 case TST_typename:
863 case TST_typeofType:
864#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
865#include "clang/Basic/TransformTypeTraits.def"
866 case TST_atomic: {
867 QualType T = DS.getRepAsType().get();
869 return true;
870 break;
871 }
872
874 case TST_typeofExpr:
875 case TST_decltype:
876 case TST_bitint:
877 if (DS.getRepAsExpr() &&
879 return true;
880 break;
881
882 case TST_unspecified:
883 case TST_void:
884 case TST_char:
885 case TST_wchar:
886 case TST_char8:
887 case TST_char16:
888 case TST_char32:
889 case TST_int:
890 case TST_int128:
891 case TST_half:
892 case TST_float:
893 case TST_double:
894 case TST_Accum:
895 case TST_Fract:
896 case TST_Float16:
897 case TST_float128:
898 case TST_ibm128:
899 case TST_bool:
900 case TST_decimal32:
901 case TST_decimal64:
902 case TST_decimal128:
903 case TST_enum:
904 case TST_union:
905 case TST_struct:
906 case TST_interface:
907 case TST_class:
908 case TST_auto:
909 case TST_auto_type:
911 case TST_BFloat16:
912#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
913#include "clang/Basic/OpenCLImageTypes.def"
915 case TST_error:
916 break;
917 }
918
919 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
920 const DeclaratorChunk &Chunk = D.getTypeObject(I);
921 switch (Chunk.Kind) {
927 // These declarator chunks cannot contain any parameter packs.
928 break;
929
931 if (Chunk.Arr.NumElts &&
933 return true;
934 break;
936 for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {
937 ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param);
938 QualType ParamTy = Param->getType();
939 assert(!ParamTy.isNull() && "Couldn't parse type?");
940 if (ParamTy->containsUnexpandedParameterPack()) return true;
941 }
942
943 if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
944 for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) {
945 if (Chunk.Fun.Exceptions[i]
946 .Ty.get()
948 return true;
949 }
950 } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) &&
952 return true;
953
954 if (Chunk.Fun.hasTrailingReturnType()) {
957 return true;
958 }
959 break;
960
962 if (Chunk.Mem.Scope().getScopeRep() &&
964 return true;
965 break;
966 }
967 }
968
969 if (Expr *TRC = D.getTrailingRequiresClause())
970 if (TRC->containsUnexpandedParameterPack())
971 return true;
972
973 return false;
974}
975
976namespace {
977
978// Callback to only accept typo corrections that refer to parameter packs.
979class ParameterPackValidatorCCC final : public CorrectionCandidateCallback {
980 public:
981 bool ValidateCandidate(const TypoCorrection &candidate) override {
982 NamedDecl *ND = candidate.getCorrectionDecl();
983 return ND && ND->isParameterPack();
984 }
985
986 std::unique_ptr<CorrectionCandidateCallback> clone() override {
987 return std::make_unique<ParameterPackValidatorCCC>(*this);
988 }
989};
990
991}
992
993/// Called when an expression computing the size of a parameter pack
994/// is parsed.
995///
996/// \code
997/// template<typename ...Types> struct count {
998/// static const unsigned value = sizeof...(Types);
999/// };
1000/// \endcode
1001///
1002//
1003/// \param OpLoc The location of the "sizeof" keyword.
1004/// \param Name The name of the parameter pack whose size will be determined.
1005/// \param NameLoc The source location of the name of the parameter pack.
1006/// \param RParenLoc The location of the closing parentheses.
1008 SourceLocation OpLoc,
1009 IdentifierInfo &Name,
1010 SourceLocation NameLoc,
1011 SourceLocation RParenLoc) {
1012 // C++0x [expr.sizeof]p5:
1013 // The identifier in a sizeof... expression shall name a parameter pack.
1014 LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
1015 LookupName(R, S);
1016
1017 NamedDecl *ParameterPack = nullptr;
1018 switch (R.getResultKind()) {
1020 ParameterPack = R.getFoundDecl();
1021 break;
1022
1025 ParameterPackValidatorCCC CCC{};
1026 if (TypoCorrection Corrected =
1027 CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr,
1028 CCC, CTK_ErrorRecovery)) {
1029 diagnoseTypo(Corrected,
1030 PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
1031 PDiag(diag::note_parameter_pack_here));
1032 ParameterPack = Corrected.getCorrectionDecl();
1033 }
1034 break;
1035 }
1038 break;
1039
1042 return ExprError();
1043 }
1044
1045 if (!ParameterPack || !ParameterPack->isParameterPack()) {
1046 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
1047 << &Name;
1048 return ExprError();
1049 }
1050
1051 MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
1052
1053 return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc,
1054 RParenLoc);
1055}
1056
1058 TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis,
1059 std::optional<unsigned> &NumExpansions) const {
1060 const TemplateArgument &Argument = OrigLoc.getArgument();
1061 assert(Argument.isPackExpansion());
1062 switch (Argument.getKind()) {
1064 // FIXME: We shouldn't ever have to worry about missing
1065 // type-source info!
1066 TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo();
1067 if (!ExpansionTSInfo)
1068 ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(),
1069 Ellipsis);
1070 PackExpansionTypeLoc Expansion =
1071 ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>();
1072 Ellipsis = Expansion.getEllipsisLoc();
1073
1074 TypeLoc Pattern = Expansion.getPatternLoc();
1075 NumExpansions = Expansion.getTypePtr()->getNumExpansions();
1076
1077 // We need to copy the TypeLoc because TemplateArgumentLocs store a
1078 // TypeSourceInfo.
1079 // FIXME: Find some way to avoid the copy?
1080 TypeLocBuilder TLB;
1081 TLB.pushFullCopy(Pattern);
1082 TypeSourceInfo *PatternTSInfo =
1083 TLB.getTypeSourceInfo(Context, Pattern.getType());
1085 PatternTSInfo);
1086 }
1087
1089 PackExpansionExpr *Expansion
1090 = cast<PackExpansionExpr>(Argument.getAsExpr());
1091 Expr *Pattern = Expansion->getPattern();
1092 Ellipsis = Expansion->getEllipsisLoc();
1093 NumExpansions = Expansion->getNumExpansions();
1094 return TemplateArgumentLoc(Pattern, Pattern);
1095 }
1096
1098 Ellipsis = OrigLoc.getTemplateEllipsisLoc();
1099 NumExpansions = Argument.getNumTemplateExpansions();
1101 OrigLoc.getTemplateQualifierLoc(),
1102 OrigLoc.getTemplateNameLoc());
1103
1110 return TemplateArgumentLoc();
1111 }
1112
1113 llvm_unreachable("Invalid TemplateArgument Kind!");
1114}
1115
1117 assert(Arg.containsUnexpandedParameterPack());
1118
1119 // If this is a substituted pack, grab that pack. If not, we don't know
1120 // the size yet.
1121 // FIXME: We could find a size in more cases by looking for a substituted
1122 // pack anywhere within this argument, but that's not necessary in the common
1123 // case for 'sizeof...(A)' handling.
1124 TemplateArgument Pack;
1125 switch (Arg.getKind()) {
1127 if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
1128 Pack = Subst->getArgumentPack();
1129 else
1130 return std::nullopt;
1131 break;
1132
1134 if (auto *Subst =
1135 dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
1136 Pack = Subst->getArgumentPack();
1137 else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) {
1138 for (VarDecl *PD : *Subst)
1139 if (PD->isParameterPack())
1140 return std::nullopt;
1141 return Subst->getNumExpansions();
1142 } else
1143 return std::nullopt;
1144 break;
1145
1149 Pack = Subst->getArgumentPack();
1150 else
1151 return std::nullopt;
1152 break;
1153
1160 return std::nullopt;
1161 }
1162
1163 // Check that no argument in the pack is itself a pack expansion.
1164 for (TemplateArgument Elem : Pack.pack_elements()) {
1165 // There's no point recursing in this case; we would have already
1166 // expanded this pack expansion into the enclosing pack if we could.
1167 if (Elem.isPackExpansion())
1168 return std::nullopt;
1169 }
1170 return Pack.pack_size();
1171}
1172
1173static void CheckFoldOperand(Sema &S, Expr *E) {
1174 if (!E)
1175 return;
1176
1177 E = E->IgnoreImpCasts();
1178 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
1179 if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) ||
1180 isa<AbstractConditionalOperator>(E)) {
1181 S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand)
1182 << E->getSourceRange()
1185 }
1186}
1187
1189 tok::TokenKind Operator,
1190 SourceLocation EllipsisLoc, Expr *RHS,
1191 SourceLocation RParenLoc) {
1192 // LHS and RHS must be cast-expressions. We allow an arbitrary expression
1193 // in the parser and reduce down to just cast-expressions here.
1194 CheckFoldOperand(*this, LHS);
1195 CheckFoldOperand(*this, RHS);
1196
1197 auto DiscardOperands = [&] {
1200 };
1201
1202 // [expr.prim.fold]p3:
1203 // In a binary fold, op1 and op2 shall be the same fold-operator, and
1204 // either e1 shall contain an unexpanded parameter pack or e2 shall contain
1205 // an unexpanded parameter pack, but not both.
1206 if (LHS && RHS &&
1209 DiscardOperands();
1210 return Diag(EllipsisLoc,
1212 ? diag::err_fold_expression_packs_both_sides
1213 : diag::err_pack_expansion_without_parameter_packs)
1214 << LHS->getSourceRange() << RHS->getSourceRange();
1215 }
1216
1217 // [expr.prim.fold]p2:
1218 // In a unary fold, the cast-expression shall contain an unexpanded
1219 // parameter pack.
1220 if (!LHS || !RHS) {
1221 Expr *Pack = LHS ? LHS : RHS;
1222 assert(Pack && "fold expression with neither LHS nor RHS");
1223 if (!Pack->containsUnexpandedParameterPack()) {
1224 DiscardOperands();
1225 return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
1226 << Pack->getSourceRange();
1227 }
1228 }
1229
1230 BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
1231
1232 // Perform first-phase name lookup now.
1233 UnresolvedLookupExpr *ULE = nullptr;
1234 {
1235 UnresolvedSet<16> Functions;
1236 LookupBinOp(S, EllipsisLoc, Opc, Functions);
1237 if (!Functions.empty()) {
1241 /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
1242 DeclarationNameInfo(OpName, EllipsisLoc), Functions);
1243 if (Callee.isInvalid())
1244 return ExprError();
1245 ULE = cast<UnresolvedLookupExpr>(Callee.get());
1246 }
1247 }
1248
1249 return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
1250 std::nullopt);
1251}
1252
1254 SourceLocation LParenLoc, Expr *LHS,
1255 BinaryOperatorKind Operator,
1256 SourceLocation EllipsisLoc, Expr *RHS,
1257 SourceLocation RParenLoc,
1258 std::optional<unsigned> NumExpansions) {
1259 return new (Context)
1260 CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator,
1261 EllipsisLoc, RHS, RParenLoc, NumExpansions);
1262}
1263
1265 BinaryOperatorKind Operator) {
1266 // [temp.variadic]p9:
1267 // If N is zero for a unary fold-expression, the value of the expression is
1268 // && -> true
1269 // || -> false
1270 // , -> void()
1271 // if the operator is not listed [above], the instantiation is ill-formed.
1272 //
1273 // Note that we need to use something like int() here, not merely 0, to
1274 // prevent the result from being a null pointer constant.
1275 QualType ScalarType;
1276 switch (Operator) {
1277 case BO_LOr:
1278 return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false);
1279 case BO_LAnd:
1280 return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true);
1281 case BO_Comma:
1282 ScalarType = Context.VoidTy;
1283 break;
1284
1285 default:
1286 return Diag(EllipsisLoc, diag::err_fold_expression_empty)
1287 << BinaryOperator::getOpcodeStr(Operator);
1288 }
1289
1290 return new (Context) CXXScalarValueInitExpr(
1291 ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc),
1292 EllipsisLoc);
1293}
static StringRef getIdentifier(const Token &Tok)
static void CheckFoldOperand(Sema &S, Expr *E)
Defines the clang::TypeLoc interface and its subclasses.
__device__ int
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:635
QualType getPackExpansionType(QualType Pattern, std::optional< unsigned > NumExpansions, bool ExpectPackInType=true)
Form a pack expansion type with the given pattern.
CanQualType DependentTy
Definition: ASTContext.h:1106
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType VoidTy
Definition: ASTContext.h:1078
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc.
Definition: Ownership.h:152
Attr - This represents one attribute.
Definition: Attr.h:40
bool isPackExpansion() const
Definition: Attr.h:97
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2170
StringRef getOpcodeStr() const
Definition: Expr.h:3879
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2242
Represents a folding of a pack over an operator.
Definition: ExprCXX.h:4674
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2151
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:73
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:214
SourceRange getRange() const
Definition: DeclSpec.h:79
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:83
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition: DeclSpec.h:94
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:409
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1238
ValueDecl * getDecl()
Definition: Expr.h:1306
SourceLocation getLocation() const
Definition: Expr.h:1314
Captures information about "declaration specifiers".
Definition: DeclSpec.h:246
TST getTypeSpecType() const
Definition: DeclSpec.h:511
ParsedType getRepAsType() const
Definition: DeclSpec.h:521
Expr * getRepAsExpr() const
Definition: DeclSpec.h:529
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
bool isParameterPack() const
Whether this declaration is a parameter pack.
Definition: DeclBase.cpp:220
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
The name of a declaration.
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function),...
NameKind getNameKind() const
Determine what kind of name this is.
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1850
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
Definition: DeclSpec.h:2319
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Definition: DeclSpec.h:1985
Expr * getTrailingRequiresClause()
Sets a trailing requires clause for this declarator.
Definition: DeclSpec.h:2554
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
Definition: DeclSpec.h:2315
This represents one expression.
Definition: Expr.h:110
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:233
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3026
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:330
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Definition: Diagnostic.h:97
One of these records is kept for each identifier that is lexed.
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:502
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1924
TemplateParameterList * getTemplateParameterList() const
If this is a generic lambda expression, retrieve the template parameter list associated with it,...
Definition: ExprCXX.cpp:1336
NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const
Retrieve the partially-substitued template parameter pack.
llvm::PointerUnion< Decl *, DeclArgumentPack * > * findInstantiationOf(const Decl *D)
Find the instantiation of the declaration D within the current instantiation scope.
Represents the results of name lookup.
Definition: Lookup.h:46
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
Definition: Lookup.h:63
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
Definition: Lookup.h:68
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
Definition: Lookup.h:73
@ NotFound
No entity found met the criteria.
Definition: Lookup.h:50
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
Definition: Lookup.h:55
@ Found
Name lookup found a single declaration that met the criteria.
Definition: Lookup.h:59
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:543
Sema::LookupNameKind getLookupKind() const
Gets the kind of lookup to perform.
Definition: Lookup.h:253
LookupResultKind getResultKind() const
Definition: Lookup.h:321
const DeclarationNameInfo & getLookupNameInfo() const
Gets the name info to look up.
Definition: Lookup.h:233
Data structure that captures multiple levels of template argument lists for use in template instantia...
Definition: Template.h:76
bool hasTemplateArgument(unsigned Depth, unsigned Index) const
Determine whether there is a non-NULL template argument at the given depth and index.
Definition: Template.h:175
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
Definition: Template.h:123
This represents a decl that may have a name.
Definition: Decl.h:247
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
A C++ nested-name-specifier augmented with source location information.
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:309
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
Definition: ExprObjC.h:359
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Definition: ExprObjC.h:361
PtrTy get() const
Definition: Ownership.h:80
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4124
Expr * getPattern()
Retrieve the pattern of the pack expansion.
Definition: ExprCXX.h:4153
std::optional< unsigned > getNumExpansions() const
Determine the number of expansions that will be produced when this pack expansion is instantiated,...
Definition: ExprCXX.h:4164
SourceLocation getEllipsisLoc() const
Retrieve the location of the ellipsis that describes this pack expansion.
Definition: ExprCXX.h:4160
void setEllipsisLoc(SourceLocation Loc)
Definition: TypeLoc.h:2529
SourceLocation getEllipsisLoc() const
Definition: TypeLoc.h:2525
TypeLoc getPatternLoc() const
Definition: TypeLoc.h:2541
Represents a pack expansion of types.
Definition: Type.h:5858
std::optional< unsigned > getNumExpansions() const
Retrieve the number of expansions that this pack expansion will generate, if known.
Definition: Type.h:5883
Represents a parameter to a function.
Definition: Decl.h:1722
Represents the parsed form of a C++ template argument.
KindType getKind() const
Determine what kind of template argument we have.
SourceLocation getLocation() const
Retrieve the location of the template argument.
ParsedTemplateTy getAsTemplate() const
Retrieve the template template argument's template name.
ParsedTemplateArgument getTemplatePackExpansion(SourceLocation EllipsisLoc) const
Retrieve a pack expansion of the given template template argument.
ParsedType getAsType() const
Retrieve the template type argument's type.
@ Type
A template type parameter, stored as a type.
@ Template
A template template argument, stored as a template name.
@ NonType
A non-type template parameter, stored as an expression.
bool isInvalid() const
Determine whether the given template argument is invalid.
Expr * getAsExpr() const
Retrieve the non-type template argument's expression.
const CXXScopeSpec & getScopeSpec() const
Retrieve the nested-name-specifier that precedes the template name in a template template argument.
A (possibly-)qualified type.
Definition: Type.h:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseTemplateArgument(const TemplateArgument &Arg)
Recursively visit a template argument and dispatch to the appropriate method for the argument type.
bool TraverseType(QualType T)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...
bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
Recursively visit a template argument location and dispatch to the appropriate method for the argumen...
bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
bool TraverseTypeLoc(TypeLoc TL)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init)
Recursively visit a lambda capture.
bool TraverseAttr(Attr *At)
Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...
bool shouldWalkTypesOfTypeLocs() const
Return whether this visitor should recurse into the types of TypeLocs.
bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base)
Recursively visit a base specifier.
bool TraverseConstructorInitializer(CXXCtorInitializer *Init)
Recursively visit a constructor initializer.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:478
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprConcepts.h:547
ArrayRef< ParmVarDecl * > getLocalParameters() const
Definition: ExprConcepts.h:513
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:356
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
Definition: SemaType.cpp:6588
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Definition: Sema.h:9814
bool containsUnexpandedParameterPacks(Declarator &D)
Determine whether the given declarator contains any unexpanded parameter packs.
bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, std::optional< unsigned > &NumExpansions)
Determine whether we could expand a pack expansion with the given set of parameter packs into separat...
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:4289
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1884
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Definition: Sema.h:803
ASTContext & Context
Definition: Sema.h:407
TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Construct a pack expansion type from the pattern of the pack expansion.
bool DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE)
If the given requirees-expression contains an unexpanded reference to one of its own parameter packs,...
void LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, UnresolvedSetImpl &Functions)
Definition: SemaExpr.cpp:15628
TemplateArgumentLoc getTemplateArgumentPackExpansionPattern(TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis, std::optional< unsigned > &NumExpansions) const
Returns the pattern of the pack expansion for a template argument.
UnexpandedParameterPackContext
The context in which an unexpanded parameter pack is being diagnosed.
Definition: Sema.h:8613
@ UPPC_Requirement
Definition: Sema.h:8678
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
bool isUnexpandedParameterPackPermitted()
Determine whether an unexpanded parameter pack might be permitted in this location.
ExprResult BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, std::optional< unsigned > NumExpansions)
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnCXXBoolLiteral - Parse {true,false} literals.
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)
Perform marking for a reference to an arbitrary declaration.
Definition: SemaExpr.cpp:20122
std::optional< unsigned > getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)
Determine the number of arguments in the given pack expansion type.
std::optional< unsigned > getFullyPackExpandedSize(TemplateArgument Arg)
Given a template argument that contains an unexpanded parameter pack, but which has already been subs...
ExprResult CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass, NestedNameSpecifierLoc NNSLoc, DeclarationNameInfo DNI, const UnresolvedSetImpl &Fns, bool PerformADL=true)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
@ CTK_ErrorRecovery
Definition: Sema.h:4527
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
void DiagnoseAmbiguousLookup(LookupResult &Result)
Produce a diagnostic describing the ambiguity that resulted from name lookup.
ExprResult ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, IdentifierInfo &Name, SourceLocation NameLoc, SourceLocation RParenLoc)
Called when an expression computing the size of a parameter pack is parsed.
ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator)
ExprResult ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, tok::TokenKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc)
Handle a C++1z fold-expression: ( expr op ... op expr ).
sema::LambdaScopeInfo * getEnclosingLambda() const
Get the innermost lambda enclosing the current location, if any.
Definition: Sema.cpp:2337
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:3121
bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc, UnexpandedParameterPackContext UPPC, ArrayRef< UnexpandedParameterPack > Unexpanded)
Diagnose unexpanded parameter packs.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
static SizeOfPackExpr * Create(ASTContext &Context, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, std::optional< unsigned > Length=std::nullopt, ArrayRef< TemplateArgument > PartialArgs=std::nullopt)
Definition: ExprCXX.cpp:1624
Encodes a location in the source.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
Stmt - This represents one statement.
Definition: Stmt.h:72
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:349
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:325
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:337
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:141
Represents the result of substituting a set of types for a template type parameter pack.
Definition: Type.h:5175
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:484
SourceLocation getLocation() const
Definition: TemplateBase.h:522
SourceLocation getTemplateEllipsisLoc() const
Definition: TemplateBase.h:581
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:533
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:574
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:541
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:567
Represents a template argument.
Definition: TemplateBase.h:60
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:368
std::optional< unsigned > getNumTemplateExpansions() const
Retrieve the number of expansions that a template template argument expansion will produce,...
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:287
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:311
bool containsUnexpandedParameterPack() const
Whether this template argument contains an unexpanded parameter pack.
TemplateArgument getPackExpansionPattern() const
When the template argument is a pack expansion, returns the pattern of the pack expansion.
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:266
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:398
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:392
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:73
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:85
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:99
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:89
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:77
@ Type
The template argument is a type.
Definition: TemplateBase.h:69
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:66
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:81
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:95
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:263
bool isPackExpansion() const
Determine whether this template argument is a pack expansion.
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
bool isNull() const
Determine whether this template name is NULL.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
bool containsUnexpandedParameterPack() const
Determines whether this template name contains an unexpanded parameter pack (for C++0x variadic templ...
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Wrapper for template type parameters.
Definition: TypeLoc.h:746
bool isParameterPack() const
Definition: Type.h:5066
unsigned getDepth() const
Definition: Type.h:5064
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void pushFullCopy(TypeLoc L)
Pushes a copy of the given TypeLoc onto this builder.
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
QualType getType() const
Get the type for which this source info wrapper provides information.
Definition: TypeLoc.h:132
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
Definition: TypeLoc.h:77
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition: TypeLoc.h:152
A container of type source information.
Definition: Type.h:6620
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:244
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6631
SourceLocation getNameLoc() const
Definition: TypeLoc.h:523
The base class of the type hierarchy.
Definition: Type.h:1566
DeducedType * getContainedDeducedType() const
Get the DeducedType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.cpp:1912
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:2005
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7424
Simple class containing the result of Sema::CorrectTypo.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3151
A set of unresolved declarations.
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3895
bool isPackExpansion() const
Determine whether this is a pack expansion.
Definition: DeclCXX.h:3941
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3798
bool isPackExpansion() const
Determine whether this is a pack expansion.
Definition: DeclCXX.h:3851
QualType getType() const
Definition: Decl.h:712
Represents a variable declaration or definition.
Definition: Decl.h:913
Contains information about the compound statement currently being parsed.
Definition: ScopeInfo.h:67
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:102
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:219
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
@ TST_typeof_unqualType
Definition: Specifiers.h:84
@ TST_ibm128
Definition: Specifiers.h:71
@ TST_decimal64
Definition: Specifiers.h:74
@ TST_float
Definition: Specifiers.h:68
@ TST_auto_type
Definition: Specifiers.h:91
@ TST_auto
Definition: Specifiers.h:89
@ TST_typeof_unqualExpr
Definition: Specifiers.h:85
@ TST_decimal32
Definition: Specifiers.h:73
@ TST_int128
Definition: Specifiers.h:61
@ TST_atomic
Definition: Specifiers.h:93
@ TST_half
Definition: Specifiers.h:63
@ TST_decltype
Definition: Specifiers.h:86
@ TST_char32
Definition: Specifiers.h:59
@ TST_struct
Definition: Specifiers.h:78
@ TST_typeofType
Definition: Specifiers.h:82
@ TST_bitint
Definition: Specifiers.h:62
@ TST_wchar
Definition: Specifiers.h:56
@ TST_BFloat16
Definition: Specifiers.h:67
@ TST_char16
Definition: Specifiers.h:58
@ TST_char
Definition: Specifiers.h:55
@ TST_unspecified
Definition: Specifiers.h:53
@ TST_class
Definition: Specifiers.h:79
@ TST_union
Definition: Specifiers.h:77
@ TST_Fract
Definition: Specifiers.h:66
@ TST_float128
Definition: Specifiers.h:70
@ TST_double
Definition: Specifiers.h:69
@ TST_Accum
Definition: Specifiers.h:65
@ TST_int
Definition: Specifiers.h:60
@ TST_bool
Definition: Specifiers.h:72
@ TST_typeofExpr
Definition: Specifiers.h:83
@ TST_typename
Definition: Specifiers.h:81
@ TST_void
Definition: Specifiers.h:54
@ TST_unknown_anytype
Definition: Specifiers.h:92
@ TST_enum
Definition: Specifiers.h:76
@ TST_error
Definition: Specifiers.h:96
@ TST_decltype_auto
Definition: Specifiers.h:90
@ TST_interface
Definition: Specifiers.h:80
@ TST_Float16
Definition: Specifiers.h:64
@ TST_char8
Definition: Specifiers.h:57
@ TST_decimal128
Definition: Specifiers.h:75
BinaryOperatorKind
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
ExprResult ExprError()
Definition: Ownership.h:278
std::pair< unsigned, unsigned > getDepthAndIndex(NamedDecl *ND)
Retrieve the depth and index of a template parameter.
Definition: SemaInternal.h:65
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1244
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl * >, SourceLocation > UnexpandedParameterPack
Definition: Sema.h:243
@ EST_Dynamic
throw(T1, T2)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
TypeSourceInfo * getNamedTypeInfo() const
getNamedTypeInfo - Returns the source type info associated to the name.
Expr * NumElts
This is the size of the array, or null if [] or [*] was specified.
Definition: DeclSpec.h:1278
bool hasTrailingReturnType() const
Determine whether this function declarator had a trailing-return-type.
Definition: DeclSpec.h:1537
TypeAndRange * Exceptions
Pointer to a new[]'d array of TypeAndRange objects that contain the types in the function's dynamic e...
Definition: DeclSpec.h:1391
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
Definition: DeclSpec.h:1379
ParsedType getTrailingReturnType() const
Get the trailing-return-type for this function declarator.
Definition: DeclSpec.h:1540
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
Definition: DeclSpec.h:1354
unsigned getNumExceptions() const
Get the number of dynamic exception specifications.
Definition: DeclSpec.h:1523
ExceptionSpecificationType getExceptionSpecType() const
Get the type of exception specification this function has.
Definition: DeclSpec.h:1518
Expr * NoexceptExpr
Pointer to the expression in the noexcept-specifier of this function, if it has one.
Definition: DeclSpec.h:1395
One instance of this struct is used for each type in a declarator that is parsed.
Definition: DeclSpec.h:1212
enum clang::DeclaratorChunk::@212 Kind
MemberPointerTypeInfo Mem
Definition: DeclSpec.h:1593
ArrayTypeInfo Arr
Definition: DeclSpec.h:1590
FunctionTypeInfo Fun
Definition: DeclSpec.h:1591
An element in an Objective-C dictionary literal.
Definition: ExprObjC.h:262
Expr * Value
The value of the dictionary element.
Definition: ExprObjC.h:267
bool isPackExpansion() const
Determines whether this dictionary element is a pack expansion.
Definition: ExprObjC.h:277
Expr * Key
The key for the dictionary element.
Definition: ExprObjC.h:264