[PATCH] D149009: [Sema]Select correct lexical context during template instantiate
Congcong Cai via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 25 19:04:57 PDT 2023
HerrCai0907 updated this revision to Diff 517019.
HerrCai0907 added a comment.
change LexicalDeclContext
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D149009/new/
https://reviews.llvm.org/D149009
Files:
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/test/SemaTemplate/template-friend-definition-in-template.cpp
Index: clang/test/SemaTemplate/template-friend-definition-in-template.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaTemplate/template-friend-definition-in-template.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+template <class F1> int foo1(F1 X1);
+
+template <int A1> struct A {
+ template <class F2> friend int foo1(F2 X2) {
+ return A1;
+ }
+};
+
+template struct A<1>;
+int main() {
+ foo1(1.0);
+}
+
+template <class F1> int foo2(F1 X1);
+
+template <int A1> struct B {
+ template <class F2> friend int foo2(F2 X2) {
+ return A1;
+ }
+};
+
+template struct B<1>;
+template int foo2<float>(float X1);
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4662,11 +4662,7 @@
ActiveInstType &ActiveInst = SemaRef.CodeSynthesisContexts.back();
if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||
ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) {
- if (FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(ActiveInst.Entity)) {
- assert(FunTmpl->getTemplatedDecl() == Tmpl &&
- "Deduction from the wrong function template?");
- (void) FunTmpl;
+ if (isa<FunctionTemplateDecl>(ActiveInst.Entity)) {
SemaRef.InstantiatingSpecializations.erase(
{ActiveInst.Entity->getCanonicalDecl(), ActiveInst.Kind});
atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst);
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3591,11 +3591,28 @@
DeclContext *Owner = FunctionTemplate->getDeclContext();
if (FunctionTemplate->getFriendObjectKind())
Owner = FunctionTemplate->getLexicalDeclContext();
+ FunctionDecl *FD = FunctionTemplate->getTemplatedDecl();
+ // additional check for inline friend,
+ // ```
+ // template <class F1> int foo(F1 X);
+ // template <int A1> struct A {
+ // template <class F1> friend int foo(F1 X) { return A1; }
+ // };
+ // template struct A<1>;
+ // int a = foo(1.0);
+ // ```
+ const FunctionDecl *FDFriend;
+ if (FD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None &&
+ FD->isDefined(FDFriend, /*CheckForPendingFriendDefinition*/ true) &&
+ FDFriend->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None) {
+ FD = const_cast<FunctionDecl *>(FDFriend);
+ Owner = FD->getLexicalDeclContext();
+ }
MultiLevelTemplateArgumentList SubstArgs(
FunctionTemplate, CanonicalDeducedArgumentList->asArray(),
/*Final=*/false);
Specialization = cast_or_null<FunctionDecl>(
- SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, SubstArgs));
+ SubstDecl(FD, Owner, SubstArgs));
if (!Specialization || Specialization->isInvalidDecl())
return TDK_SubstitutionFailure;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149009.517019.patch
Type: text/x-patch
Size: 3183 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230426/5107b2aa/attachment.bin>
More information about the cfe-commits
mailing list