diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-11 21:19:12 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-11 21:19:12 +0000 |
commit | 52604ab71a74b8ec481255dfeea7dc9dba63b1a5 (patch) | |
tree | 55ff684e046cb16edcf0341bc87cf41b05fc780a /lib/Sema/SemaTemplate.cpp | |
parent | bbbcdd9cc06b6078939129330ecc9bda3310984d (diff) |
Slight improvement for extern templates, so that an explicit
instantiation definition can follow an explicit instantiation
declaration. This is as far as I want to go with extern templates now,
but they will still need quite a bit more work to get all of the C++0x
semantics right.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81573 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 8bb33eb985..f8b48b218a 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2977,7 +2977,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, Converted, 0); Specialization->setLexicalDeclContext(CurContext); CurContext->addDecl(Specialization); - return DeclPtrTy::make(Specialization); + return DeclPtrTy::make(PrevDecl); } // If we have already (implicitly) instantiated this @@ -2985,14 +2985,19 @@ Sema::ActOnExplicitInstantiation(Scope *S, if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation) SpecializationRequiresInstantiation = false; - // Since the only prior class template specialization with these - // arguments was referenced but not declared, reuse that - // declaration node as our own, updating its source location to - // reflect our new declaration. - Specialization = PrevDecl; - Specialization->setLocation(TemplateNameLoc); - PrevDecl = 0; - } else { + if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation || + PrevDecl->getSpecializationKind() == TSK_Undeclared) { + // Since the only prior class template specialization with these + // arguments was referenced but not declared, reuse that + // declaration node as our own, updating its source location to + // reflect our new declaration. + Specialization = PrevDecl; + Specialization->setLocation(TemplateNameLoc); + PrevDecl = 0; + } + } + + if (!Specialization) { // Create a new class template specialization declaration node for // this explicit specialization. Specialization @@ -3000,10 +3005,17 @@ Sema::ActOnExplicitInstantiation(Scope *S, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, - Converted, 0); + Converted, PrevDecl); - ClassTemplate->getSpecializations().InsertNode(Specialization, - InsertPos); + if (PrevDecl) { + // Remove the previous declaration from the folding set, since we want + // to introduce a new declaration. + ClassTemplate->getSpecializations().RemoveNode(PrevDecl); + ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); + } + + // Insert the new specialization. + ClassTemplate->getSpecializations().InsertNode(Specialization, InsertPos); } // Build the fully-sugared type for this explicit instantiation as |