aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-10 17:53:52 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-10 17:53:52 +0000
commit0216f8121df32b320cab659d5b703fee50cdfda5 (patch)
tree86db4a9baa11585701e2c32ae1eed4efca0ef97a /lib/Sema/SemaTemplateDeduction.cpp
parent5429385919a2b6fb3708635b967221705f4b1daf (diff)
Repent for my copy-and-paste sins, factoring out the code that forms
argument packs from a set of deduced arguments, then checks that those argument packs match previously-deduced argument packs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123182 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp178
1 files changed, 70 insertions, 108 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index a0cbeca952..02e1a42dc3 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -543,6 +543,61 @@ static void PrepareArgumentPackDeduction(Sema &S,
}
}
+/// \brief Finish template argument deduction for a set of argument packs,
+/// producing the argument packs and checking for consistency with prior
+/// deductions.
+static Sema::TemplateDeductionResult
+FinishArgumentPackDeduction(Sema &S,
+ TemplateParameterList *TemplateParams,
+ bool HasAnyArguments,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ const llvm::SmallVectorImpl<unsigned> &PackIndices,
+ llvm::SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
+ llvm::SmallVectorImpl<
+ llvm::SmallVector<DeducedTemplateArgument, 4> > &NewlyDeducedPacks,
+ TemplateDeductionInfo &Info) {
+ // Build argument packs for each of the parameter packs expanded by this
+ // pack expansion.
+ for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
+ if (HasAnyArguments && NewlyDeducedPacks[I].empty()) {
+ // We were not able to deduce anything for this parameter pack,
+ // so just restore the saved argument pack.
+ Deduced[PackIndices[I]] = SavedPacks[I];
+ continue;
+ }
+
+ DeducedTemplateArgument NewPack;
+
+ if (NewlyDeducedPacks[I].empty()) {
+ // If we deduced an empty argument pack, create it now.
+ NewPack = DeducedTemplateArgument(TemplateArgument(0, 0));
+ } else {
+ TemplateArgument *ArgumentPack
+ = new (S.Context) TemplateArgument [NewlyDeducedPacks[I].size()];
+ std::copy(NewlyDeducedPacks[I].begin(), NewlyDeducedPacks[I].end(),
+ ArgumentPack);
+ NewPack
+ = DeducedTemplateArgument(TemplateArgument(ArgumentPack,
+ NewlyDeducedPacks[I].size()),
+ NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
+ }
+
+ DeducedTemplateArgument Result
+ = checkDeducedTemplateArguments(S.Context, SavedPacks[I], NewPack);
+ if (Result.isNull()) {
+ Info.Param
+ = makeTemplateParameter(TemplateParams->getParam(PackIndices[I]));
+ Info.FirstArg = SavedPacks[I];
+ Info.SecondArg = NewPack;
+ return Sema::TDK_Inconsistent;
+ }
+
+ Deduced[PackIndices[I]] = Result;
+ }
+
+ return Sema::TDK_Success;
+}
+
/// \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).
@@ -672,42 +727,11 @@ DeduceTemplateArguments(Sema &S,
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- if (HasAnyArguments && NewlyDeducedPacks[I].empty()) {
- // We were not able to deduce anything for this parameter pack,
- // so just restore the saved argument pack.
- Deduced[PackIndices[I]] = SavedPacks[I];
- continue;
- }
-
- DeducedTemplateArgument NewPack;
-
- if (NewlyDeducedPacks[I].empty()) {
- // If we deduced an empty argument pack, create it now.
- NewPack = DeducedTemplateArgument(TemplateArgument(0, 0));
- } else {
- TemplateArgument *ArgumentPack
- = new (S.Context) TemplateArgument [NewlyDeducedPacks[I].size()];
- std::copy(NewlyDeducedPacks[I].begin(), NewlyDeducedPacks[I].end(),
- ArgumentPack);
- NewPack
- = DeducedTemplateArgument(TemplateArgument(ArgumentPack,
- NewlyDeducedPacks[I].size()),
- NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
- }
-
- DeducedTemplateArgument Result
- = checkDeducedTemplateArguments(S.Context, SavedPacks[I], NewPack);
- if (Result.isNull()) {
- Info.Param
- = makeTemplateParameter(TemplateParams->getParam(PackIndices[I]));
- Info.FirstArg = SavedPacks[I];
- Info.SecondArg = NewPack;
- return Sema::TDK_Inconsistent;
- }
-
- Deduced[PackIndices[I]] = Result;
- }
+ if (Sema::TemplateDeductionResult Result
+ = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
+ Deduced, PackIndices, SavedPacks,
+ NewlyDeducedPacks, Info))
+ return Result;
}
// Make sure we don't have any extra arguments.
@@ -1425,42 +1449,11 @@ DeduceTemplateArguments(Sema &S,
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- if (HasAnyArguments && NewlyDeducedPacks[I].empty()) {
- // We were not able to deduce anything for this parameter pack,
- // so just restore the saved argument pack.
- Deduced[PackIndices[I]] = SavedPacks[I];
- continue;
- }
-
- DeducedTemplateArgument NewPack;
-
- if (NewlyDeducedPacks[I].empty()) {
- // If we deduced an empty argument pack, create it now.
- NewPack = DeducedTemplateArgument(TemplateArgument(0, 0));
- } else {
- TemplateArgument *ArgumentPack
- = new (S.Context) TemplateArgument [NewlyDeducedPacks[I].size()];
- std::copy(NewlyDeducedPacks[I].begin(), NewlyDeducedPacks[I].end(),
- ArgumentPack);
- NewPack
- = DeducedTemplateArgument(TemplateArgument(ArgumentPack,
- NewlyDeducedPacks[I].size()),
- NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
- }
-
- DeducedTemplateArgument Result
- = checkDeducedTemplateArguments(S.Context, SavedPacks[I], NewPack);
- if (Result.isNull()) {
- Info.Param
- = makeTemplateParameter(TemplateParams->getParam(PackIndices[I]));
- Info.FirstArg = SavedPacks[I];
- Info.SecondArg = NewPack;
- return Sema::TDK_Inconsistent;
- }
-
- Deduced[PackIndices[I]] = Result;
- }
+ if (Sema::TemplateDeductionResult Result
+ = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
+ Deduced, PackIndices, SavedPacks,
+ NewlyDeducedPacks, Info))
+ return Result;
}
// If there is an argument remaining, then we had too many arguments.
@@ -2557,42 +2550,11 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- if (HasAnyArguments && NewlyDeducedPacks[I].empty()) {
- // We were not able to deduce anything for this parameter pack,
- // so just restore the saved argument pack.
- Deduced[PackIndices[I]] = SavedPacks[I];
- continue;
- }
-
- DeducedTemplateArgument NewPack;
-
- if (NewlyDeducedPacks[I].empty()) {
- // If we deduced an empty argument pack, create it now.
- NewPack = DeducedTemplateArgument(TemplateArgument(0, 0));
- } else {
- TemplateArgument *ArgumentPack
- = new (Context) TemplateArgument [NewlyDeducedPacks[I].size()];
- std::copy(NewlyDeducedPacks[I].begin(), NewlyDeducedPacks[I].end(),
- ArgumentPack);
- NewPack
- = DeducedTemplateArgument(TemplateArgument(ArgumentPack,
- NewlyDeducedPacks[I].size()),
- NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
- }
-
- DeducedTemplateArgument Result
- = checkDeducedTemplateArguments(Context, SavedPacks[I], NewPack);
- if (Result.isNull()) {
- Info.Param
- = makeTemplateParameter(TemplateParams->getParam(PackIndices[I]));
- Info.FirstArg = SavedPacks[I];
- Info.SecondArg = NewPack;
- return Sema::TDK_Inconsistent;
- }
-
- Deduced[PackIndices[I]] = Result;
- }
+ if (Sema::TemplateDeductionResult Result
+ = FinishArgumentPackDeduction(*this, TemplateParams, HasAnyArguments,
+ Deduced, PackIndices, SavedPacks,
+ NewlyDeducedPacks, Info))
+ return Result;
// After we've matching against a parameter pack, we're done.
break;