diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-08 15:14:33 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-08 15:14:33 +0000 |
commit | f6b1185f0a8a209c06dfc1efdb6a59cc851e970c (patch) | |
tree | 32a1f28a10bdce3da2bd6477c6ed113a46c6a3a4 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 251b4ff2578e26959a4c036140ccd61c5e9292f2 (diff) |
Improve checking for specializations of member classes of class
templates, and keep track of how those member classes were
instantiated or specialized.
Make sure that we don't try to instantiate an explicitly-specialized
member class of a class template, when that explicit specialization
was a declaration rather than a definition.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83547 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 2f7af60e05..ec00d9805c 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -972,20 +972,30 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, CXXRecordDecl *Instantiation, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK) { - // FIXME: extern templates for (DeclContext::decl_iterator D = Instantiation->decls_begin(), DEnd = Instantiation->decls_end(); D != DEnd; ++D) { if (FunctionDecl *Function = dyn_cast<FunctionDecl>(*D)) { - if (Function->getInstantiatedFromMemberFunction()) + if (Function->getInstantiatedFromMemberFunction()) { + // If this member was explicitly specialized, do nothing. + if (Function->getTemplateSpecializationKind() == + TSK_ExplicitSpecialization) + continue; + Function->setTemplateSpecializationKind(TSK); - if (!Function->getBody() && TSK != TSK_ExplicitInstantiationDeclaration) + } + + if (!Function->getBody() && TSK == TSK_ExplicitInstantiationDefinition) InstantiateFunctionDefinition(PointOfInstantiation, Function); } else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) { if (Var->isStaticDataMember()) { + // If this member was explicitly specialized, do nothing. + if (Var->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + continue; + Var->setTemplateSpecializationKind(TSK); - if (TSK != TSK_ExplicitInstantiationDeclaration) + if (TSK == TSK_ExplicitInstantiationDefinition) InstantiateStaticDataMemberDefinition(PointOfInstantiation, Var); } } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(*D)) { @@ -994,6 +1004,11 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, assert(Record->getInstantiatedFromMemberClass() && "Missing instantiated-from-template information"); + + // If this member was explicitly specialized, do nothing. + if (Record->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + continue; + if (!Record->getDefinition(Context)) InstantiateClass(PointOfInstantiation, Record, Record->getInstantiatedFromMemberClass(), |