aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-08-20 01:44:21 +0000
committerJohn McCall <rjmccall@apple.com>2009-08-20 01:44:21 +0000
commite29ba20148e9b7835ad463b39cd4ee9223eafbbf (patch)
tree44ca1980c3f24bd369f292437f96d1fc06690cae /lib/Sema/SemaTemplateInstantiate.cpp
parentfafd3834754d2093e0ad7a1c005860fd527ecb7f (diff)
Basic nested-template implementation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79504 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 4d164ea12e..45214bfd6c 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -568,6 +568,38 @@ Sema::InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation,
return Invalid;
}
+/// \brief Force a template's pattern class to be instantiated.
+///
+/// \returns true if an error occurred
+bool Sema::InstantiateTemplatePattern(SourceLocation PointOfInstantiation,
+ CXXRecordDecl *Pattern) {
+ if (Pattern->getDefinition(Context)) return false;
+
+ ClassTemplateDecl *PatternTemp = Pattern->getDescribedClassTemplate();
+ if (!PatternTemp) return false;
+
+ // Check whether this template is a lazy instantiation of a
+ // dependent member template, e.g. Inner<U> in
+ // Outer<int>::Inner<U>.
+ ClassTemplateDecl *PatternPatternTemp
+ = PatternTemp->getInstantiatedFromMemberTemplate();
+ if (!PatternPatternTemp) return false;
+
+ ClassTemplateSpecializationDecl *Spec = 0;
+ for (DeclContext *Parent = Pattern->getDeclContext();
+ Parent && !Spec; Parent = Parent->getParent())
+ Spec = dyn_cast<ClassTemplateSpecializationDecl>(Parent);
+ assert(Spec && "Not a member of a class template specialization?");
+
+ // TODO: the error message from a nested failure here is probably
+ // not ideal.
+ return InstantiateClass(PointOfInstantiation,
+ Pattern,
+ PatternPatternTemp->getTemplatedDecl(),
+ Spec->getTemplateArgs(),
+ /* ExplicitInstantiation = */ false);
+}
+
/// \brief Instantiate the definition of a class from a given pattern.
///
/// \param PointOfInstantiation The point of instantiation within the
@@ -591,6 +623,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
const TemplateArgumentList &TemplateArgs,
bool ExplicitInstantiation) {
bool Invalid = false;
+
+ // Lazily instantiate member templates here.
+ if (InstantiateTemplatePattern(PointOfInstantiation, Pattern))
+ return true;
CXXRecordDecl *PatternDef
= cast_or_null<CXXRecordDecl>(Pattern->getDefinition(Context));