diff options
author | John McCall <rjmccall@apple.com> | 2009-08-20 01:44:21 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-08-20 01:44:21 +0000 |
commit | e29ba20148e9b7835ad463b39cd4ee9223eafbbf (patch) | |
tree | 44ca1980c3f24bd369f292437f96d1fc06690cae /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | fafd3834754d2093e0ad7a1c005860fd527ecb7f (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.cpp | 36 |
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)); |