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
This commit is contained in:
Douglas Gregor 2009-12-24 20:56:24 +00:00
parent 1749083e2e
commit 33636e66c7
3 changed files with 17 additions and 3 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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.