diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
commit | bb1e3bc1e0be2b8f891db46457a8943451bf4d8b (patch) | |
tree | 1e68501209c9133fbda8d45171e59f8d6f12dd55 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 77212133072dc40f070a280af8217032f55a9eb4 (diff) | |
download | FreeBSD-src-bb1e3bc1e0be2b8f891db46457a8943451bf4d8b.zip FreeBSD-src-bb1e3bc1e0be2b8f891db46457a8943451bf4d8b.tar.gz |
Updaet clang to 92395.
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8d74bd7..e909c4f 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -145,6 +145,11 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) { if (Invalid) Typedef->setInvalidDecl(); + if (TypedefDecl *Prev = D->getPreviousDeclaration()) { + NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(Prev, TemplateArgs); + Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev)); + } + Owner->addDecl(Typedef); return Typedef; @@ -396,7 +401,16 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { // FIXME: We have a problem here, because the nested call to Visit(ND) // will inject the thing that the friend references into the current // owner, which is wrong. - Decl *NewND = Visit(ND); + Decl *NewND; + + // Hack to make this work almost well pending a rewrite. + if (ND->getDeclContext()->isRecord()) + NewND = SemaRef.FindInstantiatedDecl(ND, TemplateArgs); + else if (D->wasSpecialization()) { + // Totally egregious hack to work around PR5866 + return 0; + } else + NewND = Visit(ND); if (!NewND) return 0; FU = cast<NamedDecl>(NewND); @@ -645,6 +659,12 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { CXXRecordDecl *PrevDecl = 0; if (D->isInjectedClassName()) PrevDecl = cast<CXXRecordDecl>(Owner); + else if (D->getPreviousDeclaration()) { + NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getPreviousDeclaration(), + TemplateArgs); + if (!Prev) return 0; + PrevDecl = cast<CXXRecordDecl>(Prev); + } CXXRecordDecl *Record = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner, @@ -675,7 +695,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { /// 1) instantiating function templates /// 2) substituting friend declarations /// FIXME: preserve function definitions in case #2 - Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, +Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams) { // Check whether there is already a function template specialization for // this declaration. @@ -1149,6 +1169,8 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { if (NewUD->isInvalidDecl()) return NewUD; + bool isFunctionScope = Owner->isFunctionOrMethod(); + // Process the shadow decls. for (UsingDecl::shadow_iterator I = D->shadow_begin(), E = D->shadow_end(); I != E; ++I) { @@ -1164,6 +1186,9 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { UsingShadowDecl *InstShadow = SemaRef.BuildUsingShadowDecl(/*Scope*/ 0, NewUD, InstTarget); SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow); + + if (isFunctionScope) + SemaRef.CurrentInstantiationScope->InstantiatedLocal(Shadow, InstShadow); } return NewUD; |