From: Douglas Gregor Date: Mon, 12 Oct 2009 23:11:44 +0000 (+0000) Subject: When declaring a class template whose name is qualified, make sure X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f0510d49a6985e9284d30cfc36a0df2a6292a638;p=clang When declaring a class template whose name is qualified, make sure that the scope in which it is being declared is complete. Also, when instantiating a member class template's ClassTemplateDecl, be sure to delay type creation so that the resulting type is dependent. Ick. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83923 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 8ca9089c5e..9d39ddbe68 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -574,6 +574,9 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, DeclContext *SemanticContext; LookupResult Previous; if (SS.isNotEmpty() && !SS.isInvalid()) { + if (RequireCompleteDeclContext(SS)) + return true; + SemanticContext = computeDeclContext(SS, true); if (!SemanticContext) { // FIXME: Produce a reasonable diagnostic here diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 916e443294..4fd2a734b1 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -390,7 +390,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { CXXRecordDecl *RecordInst = CXXRecordDecl::Create(SemaRef.Context, Pattern->getTagKind(), Owner, Pattern->getLocation(), Pattern->getIdentifier(), - Pattern->getTagKeywordLoc(), /*PrevDecl=*/ NULL); + Pattern->getTagKeywordLoc(), /*PrevDecl=*/ NULL, + /*DelayTypeCreation=*/true); ClassTemplateDecl *Inst = ClassTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(), @@ -398,7 +399,10 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { RecordInst->setDescribedClassTemplate(Inst); Inst->setAccess(D->getAccess()); Inst->setInstantiatedFromMemberTemplate(D); - + + // Trigger creation of the type for the instantiation. + SemaRef.Context.getTypeDeclType(RecordInst); + Owner->addDecl(Inst); return Inst; } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp new file mode 100644 index 0000000000..112444af95 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template class A { + template class B { + template void mf1(T3); + void mf2(); + }; +}; + +template<> template +class A::B { }; + +template<> template<> template + void A::B::mf1(T t) { } + +template template<> + void A::B::mf2() { } // expected-error{{does not refer}}