[clang] [C++20] [Modules] Support generating in-class defined function with try-catch body (PR #129212)

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 4 18:11:04 PST 2025


https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/129212

>From 8876ef70a08f8547d49b89275a3b1b455221abd0 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Fri, 28 Feb 2025 17:03:49 +0800
Subject: [PATCH 1/3] [C++20] [Modules] Support generating in-class defined
 function with try-catch body

See the example:

```
export module func;
class C {
public:
    void member() try {

    } catch (...) {

    }
};
```

We woudln't generate the definition for `C::member` but we should. Since
the function is non-inline in modules.

This turns out to be an oversight in parser to me. Since the try-catch
body is relatively rare, so maybe we just forgot it.
---
 clang/lib/Parse/ParseCXXInlineMethods.cpp |  5 +++++
 clang/test/Modules/try-func-body.cppm     | 13 +++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 clang/test/Modules/try-func-body.cppm

diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 6c01af55ef3c4..723ebfa59fc03 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -632,6 +632,11 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
 
     if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
       ConsumeAnyToken();
+
+    if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
+      if (isa<CXXMethodDecl>(FD) ||
+          FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
+        Actions.ActOnFinishInlineFunctionDef(FD);
     return;
   }
   if (Tok.is(tok::colon)) {
diff --git a/clang/test/Modules/try-func-body.cppm b/clang/test/Modules/try-func-body.cppm
new file mode 100644
index 0000000000000..379f5e47f4f8e
--- /dev/null
+++ b/clang/test/Modules/try-func-body.cppm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+export module func;
+class C {
+public:
+    void member() try {
+
+    } catch (...) {
+
+    }
+};
+
+// CHECK: define {{.*}}@_ZNW4func1C6memberEv

>From deb965a5ff5e94dcd860cd6c28ecbafda90ae3cf Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Tue, 4 Mar 2025 10:05:26 +0800
Subject: [PATCH 2/3] Update

---
 clang/lib/Parse/ParseCXXInlineMethods.cpp | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 723ebfa59fc03..3b440743a4c59 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -17,6 +17,7 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Scope.h"
+#include "llvm/ADT/ScopeExit.h"
 
 using namespace clang;
 
@@ -624,6 +625,13 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
 
   Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
 
+  auto _ = llvm::make_scope_exit([&]() {
+    if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
+      if (isa<CXXMethodDecl>(FD) ||
+          FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
+        Actions.ActOnFinishInlineFunctionDef(FD);
+  });
+
   if (Tok.is(tok::kw_try)) {
     ParseFunctionTryBlock(LM.D, FnScope);
 
@@ -632,11 +640,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
 
     if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
       ConsumeAnyToken();
-
-    if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
-      if (isa<CXXMethodDecl>(FD) ||
-          FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
-        Actions.ActOnFinishInlineFunctionDef(FD);
     return;
   }
   if (Tok.is(tok::colon)) {
@@ -671,11 +674,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
 
   if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
     ConsumeAnyToken();
-
-  if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
-    if (isa<CXXMethodDecl>(FD) ||
-        FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
-      Actions.ActOnFinishInlineFunctionDef(FD);
 }
 
 /// ParseLexedMemberInitializers - We finished parsing the member specification

>From debbd847ec414c84d6c120f9e08e3371e5eea34e Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Wed, 5 Mar 2025 10:10:41 +0800
Subject: [PATCH 3/3] Update

---
 clang/lib/Parse/ParseCXXInlineMethods.cpp | 24 ++++++-----------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 3b440743a4c59..b1064eb02b907 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -626,6 +626,12 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
   Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
 
   auto _ = llvm::make_scope_exit([&]() {
+    while (Tok.isNot(tok::eof))
+      ConsumeAnyToken();
+
+    if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
+      ConsumeAnyToken();
+
     if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
       if (isa<CXXMethodDecl>(FD) ||
           FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
@@ -634,12 +640,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
 
   if (Tok.is(tok::kw_try)) {
     ParseFunctionTryBlock(LM.D, FnScope);
-
-    while (Tok.isNot(tok::eof))
-      ConsumeAnyToken();
-
-    if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
-      ConsumeAnyToken();
     return;
   }
   if (Tok.is(tok::colon)) {
@@ -649,12 +649,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
     if (!Tok.is(tok::l_brace)) {
       FnScope.Exit();
       Actions.ActOnFinishFunctionBody(LM.D, nullptr);
-
-      while (Tok.isNot(tok::eof))
-        ConsumeAnyToken();
-
-      if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
-        ConsumeAnyToken();
       return;
     }
   } else
@@ -668,12 +662,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
          "current template being instantiated!");
 
   ParseFunctionStatementBody(LM.D, FnScope);
-
-  while (Tok.isNot(tok::eof))
-    ConsumeAnyToken();
-
-  if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
-    ConsumeAnyToken();
 }
 
 /// ParseLexedMemberInitializers - We finished parsing the member specification



More information about the cfe-commits mailing list