From 33636e66c7a7744b044117d904fb08e0abcc6bb2 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 24 Dec 2009 20:56:24 +0000 Subject: [PATCH] Egregious, disgusting workaround for PR5866. We need to rework how we keep track of friends within templates, which will provide a real for PR5866. For now, this makes sure we don't do something entirely stupid with friends of specializations. llvm-svn: 92143 --- clang/include/clang/AST/DeclCXX.h | 10 +++++++++- clang/lib/Sema/SemaDeclCXX.cpp | 3 +++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 +++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index c1975505372b..02581c1241a4 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1338,11 +1338,16 @@ private: // Location of the 'friend' specifier. SourceLocation FriendLoc; + // FIXME: Hack to keep track of whether this was a friend function + // template specialization. + bool WasSpecialization; + FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, SourceLocation FriendL) : Decl(Decl::Friend, DC, L), Friend(Friend), - FriendLoc(FriendL) { + FriendLoc(FriendL), + WasSpecialization(false) { } public: @@ -1369,6 +1374,9 @@ public: return FriendLoc; } + bool wasSpecialization() const { return WasSpecialization; } + void setSpecialization(bool WS) { WasSpecialization = WS; } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == Decl::Friend; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 2e4ee63ebdb5..b70b0dccb75e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5380,6 +5380,9 @@ Sema::ActOnFriendFunctionDecl(Scope *S, FrD->setAccess(AS_public); CurContext->addDecl(FrD); + if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) + FrD->setSpecialization(true); + return DeclPtrTy::make(ND); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 18a73250a529..1ec91bd55ec3 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -401,7 +401,10 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { // Hack to make this work almost well pending a rewrite. if (ND->getDeclContext()->isRecord()) NewND = SemaRef.FindInstantiatedDecl(ND, TemplateArgs); - else + else if (D->wasSpecialization()) { + // Totally egregious hack to work around PR5866 + return 0; + } else NewND = Visit(ND); if (!NewND) return 0; @@ -687,7 +690,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.