[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

Iain Sandoe via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 27 04:19:04 PST 2023


iains created this revision.
Herald added a project: All.
iains added reviewers: dblaikie, ChuanqiXu.
iains published this revision for review.
iains added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

@dblaikie - I suspect that this would be useful on the llvm-16 release branch, and so I've added you as a reviewer, if you have some chance to look ..
 (I do not think @ChuanqiXu is available until February).

The issue here is that the function decl is extracted from function templates (and looks just like any other function definition at this point), so that we need to remember that it came from a template.


This addresses part of https://github.com/llvm/llvm-project/issues/60079

The test for external functions was not considering function templates.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142704

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===================================================================
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
     // This is a declaration instead of definition.
@@ -36,3 +38,10 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template<class _Ep>
+int tmpl_OK (_Ep) { return 0; }
+
+template <class _T1>
+bool
+operator==(_T1& , _T1& ) { return false; }
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15108,10 +15108,12 @@
   }
 
   FunctionDecl *FD = nullptr;
+  bool IsFnTemplate = false;
 
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) {
     FD = FunTmpl->getTemplatedDecl();
-  else
+    IsFnTemplate = true;
+  } else
     FD = cast<FunctionDecl>(D);
 
   // Do not push if it is a lambda because one is already pushed when building
@@ -15260,7 +15262,7 @@
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
       FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-      !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+      !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete &&
       BodyKind != FnBodyKind::Default && !FD->isInlined()) {
     assert(FD->isThisDeclarationADefinition());
     Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142704.492700.patch
Type: text/x-patch
Size: 1793 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230127/c29bb514/attachment.bin>


More information about the cfe-commits mailing list