[PATCH] D149009: [Sema]Select correct lexical context during template instantiate

Congcong Cai via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 22 22:42:30 PDT 2023


HerrCai0907 created this revision.
HerrCai0907 added reviewers: aaron.ballman, erichkeane, shafik.
Herald added a project: All.
HerrCai0907 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch wants to fix inline friend decl like

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149009

Files:
  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,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+template <class F1> int foo(F1 X1);
+
+template <int A1> struct A {
+  template <class F2> friend int foo(F2 X2) {
+    return A1;
+  }
+};
+
+template struct A<1>;
+int main() { 
+  foo(1.0);
+}
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2028,9 +2028,12 @@
 Decl *TemplateDeclInstantiator::VisitFunctionDecl(
     FunctionDecl *D, TemplateParameterList *TemplateParams,
     RewriteKind FunctionRewriteKind) {
+  const FunctionDecl *Definition = D;
+  D->isDefined(Definition, true);
+    
   // Check whether there is already a function template specialization for
   // this declaration.
-  FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
+  FunctionTemplateDecl *FunctionTemplate = Definition->getDescribedFunctionTemplate();
   if (FunctionTemplate && !TemplateParams) {
     ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
 
@@ -2152,11 +2155,11 @@
   if (!isFriend && D->isOutOfLine() && !D->isLocalExternDecl()) {
     assert(D->getDeclContext()->isFileContext());
     LexicalDC = D->getDeclContext();
-  }
-  else if (D->isLocalExternDecl()) {
+  } else if (D->isLocalExternDecl()) {
     LexicalDC = SemaRef.CurContext;
+  } else if (isFriend && Definition != D) {
+    LexicalDC = const_cast<DeclContext *>(Definition->getLexicalDeclContext());
   }
-
   Function->setLexicalDeclContext(LexicalDC);
 
   // Attach the parameters


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149009.516119.patch
Type: text/x-patch
Size: 1894 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230423/c9f4d41e/attachment.bin>


More information about the cfe-commits mailing list