diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-12-21 00:52:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-12-21 00:52:54 +0000 |
commit | b99268b3083c882103bd1bd08bdcc9a76a2b4795 (patch) | |
tree | 92882d13fbae07610f2dac6fdd5d46f68b9b126f /lib/Sema/SemaTemplateVariadic.cpp | |
parent | 00ccbefcffeb88ea3e2e6323e594fa968753ad14 (diff) |
Implement instantiation of pack expansions whose pattern is a type-id
in an exception specification.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122297 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 681bc8d072..f2651ef65c 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -259,6 +259,11 @@ void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, .TraverseTemplateArgumentLoc(Arg); } +void Sema::collectUnexpandedParameterPacks(QualType T, + llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { + CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T); +} + ParsedTemplateArgument Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc) { @@ -327,3 +332,78 @@ TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, Pattern->getTypeLoc().getFullDataSize()); return TSResult; } + + +bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, + SourceRange PatternRange, + const UnexpandedParameterPack *Unexpanded, + unsigned NumUnexpanded, + const MultiLevelTemplateArgumentList &TemplateArgs, + bool &ShouldExpand, + unsigned &NumExpansions) { + ShouldExpand = true; + std::pair<IdentifierInfo *, SourceLocation> FirstPack; + bool HaveFirstPack = false; + + for (unsigned I = 0; I != NumUnexpanded; ++I) { + // Compute the depth and index for this parameter pack. + unsigned Depth; + unsigned Index; + IdentifierInfo *Name; + + if (const TemplateTypeParmType *TTP + = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { + Depth = TTP->getDepth(); + Index = TTP->getIndex(); + Name = TTP->getName(); + } else { + NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>(); + if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) { + Depth = TTP->getDepth(); + Index = TTP->getIndex(); + } else if (NonTypeTemplateParmDecl *NTTP + = dyn_cast<NonTypeTemplateParmDecl>(ND)) { + Depth = NTTP->getDepth(); + Index = NTTP->getIndex(); + } else { + TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND); + Depth = TTP->getDepth(); + Index = TTP->getIndex(); + } + // FIXME: Variadic templates function parameter packs? + Name = ND->getIdentifier(); + } + + // If we don't have a template argument at this depth/index, then we + // cannot expand the pack expansion. Make a note of this, but we still + // want to check that any parameter packs we *do* have arguments for. + if (!TemplateArgs.hasTemplateArgument(Depth, Index)) { + ShouldExpand = false; + continue; + } + + // Determine the size of the argument pack. + unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size(); + if (!HaveFirstPack) { + // The is the first pack we've seen for which we have an argument. + // Record it. + NumExpansions = NewPackSize; + FirstPack.first = Name; + FirstPack.second = Unexpanded[I].second; + HaveFirstPack = true; + continue; + } + + if (NewPackSize != NumExpansions) { + // C++0x [temp.variadic]p5: + // All of the parameter packs expanded by a pack expansion shall have + // the same number of arguments specified. + Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) + << FirstPack.first << Name << NumExpansions << NewPackSize + << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second); + return true; + } + } + + return false; +} |