summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorSerge Pavlov <sepavloff@gmail.com>2018-12-06 09:35:04 +0000
committerSerge Pavlov <sepavloff@gmail.com>2018-12-06 09:35:04 +0000
commitacfcd78aec83512807718605faf698a20af26fdd (patch)
treedca76f2f8b300d6c7760f4ee0035e56bbb84eacc /clang/lib/Sema/SemaDecl.cpp
parent1027249ec908cb8ccac238953ee969bc7e6d40aa (diff)
downloadbcm5719-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.cpp23
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;
OpenPOWER on IntegriCloud