From 869853eea1a876b44b369b3b439d7b42de8692ec Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 10 Nov 2010 19:44:59 +0000 Subject: Instantiate class member template partial specialization declarations in the order they occur within the class template, delaying out-of-line member template partial specializations until after the class has been fully instantiated. This fixes a regression introduced by r118454 (itself a fix for PR8001). llvm-svn: 118704 --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp') diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index af9af0ab83a..3468a3d93f6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1221,6 +1221,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs)) Invalid = true; + TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs); llvm::SmallVector Fields; for (RecordDecl::decl_iterator Member = Pattern->decls_begin(), MemberEnd = Pattern->decls_end(); @@ -1237,7 +1238,12 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, if ((*Member)->getDeclContext() != Pattern) continue; - Decl *NewMember = SubstDecl(*Member, Instantiation, TemplateArgs); + if ((*Member)->isInvalidDecl()) { + Invalid = true; + continue; + } + + Decl *NewMember = Instantiator.Visit(*Member); if (NewMember) { if (FieldDecl *Field = dyn_cast(NewMember)) Fields.push_back(Field); @@ -1257,7 +1263,22 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, CheckCompletedCXXClass(Instantiation); if (Instantiation->isInvalidDecl()) Invalid = true; - + else { + // Instantiate any out-of-line class template partial + // specializations now. + for (TemplateDeclInstantiator::delayed_partial_spec_iterator + P = Instantiator.delayed_partial_spec_begin(), + PEnd = Instantiator.delayed_partial_spec_end(); + P != PEnd; ++P) { + if (!Instantiator.InstantiateClassTemplatePartialSpecialization( + P->first, + P->second)) { + Invalid = true; + break; + } + } + } + // Exit the scope of this instantiation. SavedContext.pop(); -- cgit v1.2.3