diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-18 01:29:05 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-18 01:29:05 +0000 |
commit | 500d729e85028944355a119f9823ac99fa5ddcab (patch) | |
tree | 4c61dbac98164c678af990611d511df3c6915afc /lib/Sema/SemaTemplateVariadic.cpp | |
parent | 5912597f3a01f6b5a6f6c5543317d209dbbb0a87 (diff) |
PR13386: When matching up parameters between a function template declaration
and a function template instantiation, if there's a parameter pack in the
declaration and one at the same place in the instantiation, don't assume that
the pack wasn't expanded -- it may have expanded to nothing. Instead, go ahead
and check whether the parameter pack was expandable. We can do this as a
side-effect of the work we'd need to do anyway, to find how many parameters
were produced.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160416 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index a40100c7a7..0d0f992bed 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -597,12 +597,13 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, return false; } -unsigned Sema::getNumArgumentsInExpansion(QualType T, +llvm::Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs) { QualType Pattern = cast<PackExpansionType>(T)->getPattern(); SmallVector<UnexpandedParameterPack, 2> Unexpanded; CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); + llvm::Optional<unsigned> Result; for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { // Compute the depth and index for this parameter pack. unsigned Depth; @@ -621,9 +622,14 @@ unsigned Sema::getNumArgumentsInExpansion(QualType T, llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation = CurrentInstantiationScope->findInstantiationOf( Unexpanded[I].first.get<NamedDecl *>()); - if (Instantiation->is<DeclArgumentPack *>()) - return Instantiation->get<DeclArgumentPack *>()->size(); - + if (Instantiation->is<Decl*>()) + // The pattern refers to an unexpanded pack. We're not ready to expand + // this pack yet. + return llvm::Optional<unsigned>(); + + unsigned Size = Instantiation->get<DeclArgumentPack *>()->size(); + assert((!Result || *Result == Size) && "inconsistent pack sizes"); + Result = Size; continue; } @@ -631,13 +637,17 @@ unsigned Sema::getNumArgumentsInExpansion(QualType T, } if (Depth >= TemplateArgs.getNumLevels() || !TemplateArgs.hasTemplateArgument(Depth, Index)) - continue; + // The pattern refers to an unknown template argument. We're not ready to + // expand this pack yet. + return llvm::Optional<unsigned>(); // Determine the size of the argument pack. - return TemplateArgs(Depth, Index).pack_size(); + unsigned Size = TemplateArgs(Depth, Index).pack_size(); + assert((!Result || *Result == Size) && "inconsistent pack sizes"); + Result = Size; } - llvm_unreachable("No unexpanded parameter packs in type expansion."); + return Result; } bool Sema::containsUnexpandedParameterPacks(Declarator &D) { |