aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-05-31 09:31:02 +0000
committerDouglas Gregor <dgregor@apple.com>2009-05-31 09:31:02 +0000
commitc8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003 (patch)
treef88bd5a5e94527a2040562782a00cab2e9d9bebe /lib/Sema/SemaTemplateInstantiate.cpp
parentf757ae711513e5b2efa25fde1562315c0906bd68 (diff)
Initial infrastructure for class template partial specialization. Here
we have the basics of declaring and storing class template partial specializations, matching class template partial specializations at instantiation time via (limited) template argument deduction, and using the class template partial specialization's pattern for instantiation. This patch is enough to make a simple is_pointer type trait work, but not much else. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72662 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 3cac739818..d3d771b0eb 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -822,14 +822,34 @@ Sema::InstantiateClassTemplateSpecialization(
if (ClassTemplateSpec->getSpecializationKind() != TSK_Undeclared)
return true;
- // FIXME: Push this class template instantiation onto the instantiation stack,
- // checking for recursion that exceeds a certain depth.
-
- // FIXME: Perform class template partial specialization to select the best
- // template.
ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
-
CXXRecordDecl *Pattern = Template->getTemplatedDecl();
+ const TemplateArgumentList *TemplateArgs
+ = &ClassTemplateSpec->getTemplateArgs();
+
+ // Determine whether any class template partial specializations
+ // match the given template arguments.
+ llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> Matched;
+ for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+ Partial = Template->getPartialSpecializations().begin(),
+ PartialEnd = Template->getPartialSpecializations().end();
+ Partial != PartialEnd;
+ ++Partial) {
+ if (DeduceTemplateArguments(&*Partial, ClassTemplateSpec->getTemplateArgs()))
+ Matched.push_back(&*Partial);
+ }
+
+ if (Matched.size() == 1) {
+ Pattern = Matched[0];
+ // FIXME: set TemplateArgs to the template arguments of the
+ // partial specialization, instantiated with the deduced template
+ // arguments.
+ } else if (Matched.size() > 1) {
+ // FIXME: Implement partial ordering of class template partial
+ // specializations.
+ Diag(ClassTemplateSpec->getLocation(),
+ diag::unsup_template_partial_spec_ordering);
+ }
// Note that this is an instantiation.
ClassTemplateSpec->setSpecializationKind(
@@ -837,8 +857,7 @@ Sema::InstantiateClassTemplateSpecialization(
: TSK_ImplicitInstantiation);
return InstantiateClass(ClassTemplateSpec->getLocation(),
- ClassTemplateSpec, Pattern,
- ClassTemplateSpec->getTemplateArgs(),
+ ClassTemplateSpec, Pattern, *TemplateArgs,
ExplicitInstantiation);
}