aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-25 21:17:03 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-25 21:17:03 +0000
commitd475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4d (patch)
tree9e94affff617c4a7717084c00c8f14f431d73bd9 /lib/Sema/SemaType.cpp
parent4fcb4cd6556cd783b2a8cd2b7266ae4696e605bb (diff)
Instantiation for member classes of class templates. Note that only
the declarations of member classes are instantiated when the owning class template is instantiated. The definitions of such member classes are instantiated when a complete type is required. This change also introduces the injected-class-name into a class template specialization. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67707 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 196a30642b..4b2565795a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1042,11 +1042,11 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag,
if (!T->isIncompleteType())
return false;
- // If we have a class template specialization, try to instantiate
- // it.
- if (const RecordType *Record = T->getAsRecordType())
+ // If we have a class template specialization or a class member of a
+ // class template specialization, try to instantiate it.
+ if (const RecordType *Record = T->getAsRecordType()) {
if (ClassTemplateSpecializationDecl *ClassTemplateSpec
- = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl()))
+ = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
// Update the class template specialization's location to
// refer to the point of instantiation.
@@ -1055,7 +1055,22 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag,
return InstantiateClassTemplateSpecialization(ClassTemplateSpec,
/*ExplicitInstantiation=*/false);
}
-
+ } else if (CXXRecordDecl *Rec
+ = dyn_cast<CXXRecordDecl>(Record->getDecl())) {
+ if (CXXRecordDecl *Pattern = Rec->getInstantiatedFromMemberClass()) {
+ // Find the class template specialization that surrounds this
+ // member class.
+ ClassTemplateSpecializationDecl *Spec = 0;
+ for (DeclContext *Parent = Rec->getDeclContext();
+ Parent && !Spec; Parent = Parent->getParent())
+ Spec = dyn_cast<ClassTemplateSpecializationDecl>(Parent);
+ assert(Spec && "Not a member of a class template specialization?");
+ return InstantiateClass(Loc, Rec, Pattern,
+ Spec->getTemplateArgs(),
+ Spec->getNumTemplateArgs());
+ }
+ }
+ }
if (PrintType.isNull())
PrintType = T;