aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-10 17:35:05 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-10 17:35:05 +0000
commit5429385919a2b6fb3708635b967221705f4b1daf (patch)
tree9c1a5d653a7a2f849733d3ae96eb29eb79fe2810
parent26c9cb55cb96643c0759c08d037c16c309864087 (diff)
Factor out the code to set up template argument deduction for a set of
template argument packs. This also ensures that explicitly-specified template arguments get properly represented in those cases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123180 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp90
1 files changed, 40 insertions, 50 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index ff084c34c2..a0cbeca952 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -512,6 +512,37 @@ static TemplateParameter makeTemplateParameter(Decl *D) {
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
+/// \brief Prepare to perform template argument deduction for all of the
+/// arguments in a set of argument packs.
+static void PrepareArgumentPackDeduction(Sema &S,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ const llvm::SmallVectorImpl<unsigned> &PackIndices,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
+ llvm::SmallVectorImpl<
+ llvm::SmallVector<DeducedTemplateArgument, 4> > &NewlyDeducedPacks) {
+ // Save the deduced template arguments for each parameter pack expanded
+ // by this pack expansion, then clear out the deduction.
+ for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
+ // Save the previously-deduced argument pack, then clear it out so that we
+ // can deduce a new argument pack.
+ SavedPacks[I] = Deduced[PackIndices[I]];
+ Deduced[PackIndices[I]] = TemplateArgument();
+
+ // If the template arugment pack was explicitly specified, add that to
+ // the set of deduced arguments.
+ const TemplateArgument *ExplicitArgs;
+ unsigned NumExplicitArgs;
+ if (NamedDecl *PartiallySubstitutedPack
+ = S.CurrentInstantiationScope->getPartiallySubstitutedPack(
+ &ExplicitArgs,
+ &NumExplicitArgs)) {
+ if (getDepthAndIndex(PartiallySubstitutedPack).second == PackIndices[I])
+ NewlyDeducedPacks[I].append(ExplicitArgs,
+ ExplicitArgs + NumExplicitArgs);
+ }
+ }
+}
+
/// \brief Deduce the template arguments by comparing the list of parameter
/// types to the list of argument types, as in the parameter-type-lists of
/// function types (C++ [temp.deduct.type]p10).
@@ -612,28 +643,10 @@ DeduceTemplateArguments(Sema &S,
// template argument (the inner SmallVectors).
llvm::SmallVector<llvm::SmallVector<DeducedTemplateArgument, 4>, 2>
NewlyDeducedPacks(PackIndices.size());
-
- // Save the deduced template arguments for each parameter pack expanded
- // by this pack expansion, then clear out the deduction.
llvm::SmallVector<DeducedTemplateArgument, 2>
- SavedPacks(PackIndices.size());
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- SavedPacks[I] = Deduced[PackIndices[I]];
- Deduced[PackIndices[I]] = DeducedTemplateArgument();
-
- // If the template arugment pack was explicitly specified, add that to
- // the set of deduced arguments.
- const TemplateArgument *ExplicitArgs;
- unsigned NumExplicitArgs;
- if (NamedDecl *PartiallySubstitutedPack
- = S.CurrentInstantiationScope->getPartiallySubstitutedPack(
- &ExplicitArgs,
- &NumExplicitArgs)) {
- if (getDepthAndIndex(PartiallySubstitutedPack).second == PackIndices[I])
- NewlyDeducedPacks[I].append(ExplicitArgs,
- ExplicitArgs + NumExplicitArgs);
- }
- }
+ SavedPacks(PackIndices.size());
+ PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
+ NewlyDeducedPacks);
bool HasAnyArguments = false;
for (; ArgIdx < NumArgs; ++ArgIdx) {
@@ -1378,16 +1391,14 @@ DeduceTemplateArguments(Sema &S,
// by this pack expansion, then clear out the deduction.
llvm::SmallVector<DeducedTemplateArgument, 2>
SavedPacks(PackIndices.size());
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- SavedPacks[I] = Deduced[PackIndices[I]];
- Deduced[PackIndices[I]] = DeducedTemplateArgument();
- }
+ llvm::SmallVector<llvm::SmallVector<DeducedTemplateArgument, 4>, 2>
+ NewlyDeducedPacks(PackIndices.size());
+ PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
+ NewlyDeducedPacks);
// Keep track of the deduced template arguments for each parameter pack
// expanded by this pack expansion (the outer index) and for each
// template argument (the inner SmallVectors).
- llvm::SmallVector<llvm::SmallVector<DeducedTemplateArgument, 4>, 2>
- NewlyDeducedPacks(PackIndices.size());
bool HasAnyArguments = false;
while (hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs)) {
HasAnyArguments = true;
@@ -2505,31 +2516,10 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// template argument (the inner SmallVectors).
llvm::SmallVector<llvm::SmallVector<DeducedTemplateArgument, 4>, 2>
NewlyDeducedPacks(PackIndices.size());
-
- // Save the deduced template arguments for each parameter pack expanded
- // by this pack expansion, then clear out the deduction.
llvm::SmallVector<DeducedTemplateArgument, 2>
SavedPacks(PackIndices.size());
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- // Save the previously-deduced argument pack, then clear it out so that we
- // can deduce a new argument pack.
- SavedPacks[I] = Deduced[PackIndices[I]];
- Deduced[PackIndices[I]] = TemplateArgument();
-
- // If the template arugment pack was explicitly specified, add that to
- // the set of deduced arguments.
- const TemplateArgument *ExplicitArgs;
- unsigned NumExplicitArgs;
- if (NamedDecl *PartiallySubstitutedPack
- = CurrentInstantiationScope->getPartiallySubstitutedPack(
- &ExplicitArgs,
- &NumExplicitArgs)) {
- if (getDepthAndIndex(PartiallySubstitutedPack).second == PackIndices[I])
- NewlyDeducedPacks[I].append(ExplicitArgs,
- ExplicitArgs + NumExplicitArgs);
- }
- }
-
+ PrepareArgumentPackDeduction(*this, Deduced, PackIndices, SavedPacks,
+ NewlyDeducedPacks);
bool HasAnyArguments = false;
for (; ArgIdx < NumArgs; ++ArgIdx) {
HasAnyArguments = true;