diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2018-12-06 09:35:04 +0000 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2018-12-06 09:35:04 +0000 |
commit | acfcd78aec83512807718605faf698a20af26fdd (patch) | |
tree | dca76f2f8b300d6c7760f4ee0035e56bbb84eacc /clang/lib/Sema/SemaDecl.cpp | |
parent | 1027249ec908cb8ccac238953ee969bc7e6d40aa (diff) | |
download | bcm5719-llvm-acfcd78aec83512807718605faf698a20af26fdd.tar.gz bcm5719-llvm-acfcd78aec83512807718605faf698a20af26fdd.zip |
Diagnose friend function template redefinitions.
Friend function template defined in a class template becomes available if
the enclosing class template is instantiated. Until the function template
is used, it does not have a body, but still is considered a definition for
the purpose of redeclaration checks.
This change modifies redefinition check so that it can find the friend
function template definitions in instantiated classes.
Differential Revision: http://reviews.llvm.org/D21508
llvm-svn: 348473
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 083089fc994..a4545f2ff63 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12737,6 +12737,29 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, } } } + + if (!Definition) + // Similar to friend functions a friend function template may be a + // definition and do not have a body if it is instantiated in a class + // template. + if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) { + for (auto I : FTD->redecls()) { + auto D = cast<FunctionTemplateDecl>(I); + if (D != FTD) { + assert(!D->isThisDeclarationADefinition() && + "More than one definition in redeclaration chain"); + if (D->getFriendObjectKind() != Decl::FOK_None) + if (FunctionTemplateDecl *FT = + D->getInstantiatedFromMemberTemplate()) { + if (FT->isThisDeclarationADefinition()) { + Definition = D->getTemplatedDecl(); + break; + } + } + } + } + } + if (!Definition) return; |