Skip to content

Commit 68427bc

Browse files
authored
[C++20] [Modules] Support generating in-class defined function with try-catch body (#129212)
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.
1 parent 30fd3c6 commit 68427bc

File tree

2 files changed

+24
-20
lines changed

2 files changed

+24
-20
lines changed

clang/lib/Parse/ParseCXXInlineMethods.cpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/Sema/DeclSpec.h"
1818
#include "clang/Sema/EnterExpressionEvaluationContext.h"
1919
#include "clang/Sema/Scope.h"
20+
#include "llvm/ADT/ScopeExit.h"
2021

2122
using namespace clang;
2223

@@ -624,14 +625,21 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
624625

625626
Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
626627

627-
if (Tok.is(tok::kw_try)) {
628-
ParseFunctionTryBlock(LM.D, FnScope);
629-
628+
auto _ = llvm::make_scope_exit([&]() {
630629
while (Tok.isNot(tok::eof))
631630
ConsumeAnyToken();
632631

633632
if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
634633
ConsumeAnyToken();
634+
635+
if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
636+
if (isa<CXXMethodDecl>(FD) ||
637+
FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
638+
Actions.ActOnFinishInlineFunctionDef(FD);
639+
});
640+
641+
if (Tok.is(tok::kw_try)) {
642+
ParseFunctionTryBlock(LM.D, FnScope);
635643
return;
636644
}
637645
if (Tok.is(tok::colon)) {
@@ -641,12 +649,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
641649
if (!Tok.is(tok::l_brace)) {
642650
FnScope.Exit();
643651
Actions.ActOnFinishFunctionBody(LM.D, nullptr);
644-
645-
while (Tok.isNot(tok::eof))
646-
ConsumeAnyToken();
647-
648-
if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
649-
ConsumeAnyToken();
650652
return;
651653
}
652654
} else
@@ -660,17 +662,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
660662
"current template being instantiated!");
661663

662664
ParseFunctionStatementBody(LM.D, FnScope);
663-
664-
while (Tok.isNot(tok::eof))
665-
ConsumeAnyToken();
666-
667-
if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
668-
ConsumeAnyToken();
669-
670-
if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
671-
if (isa<CXXMethodDecl>(FD) ||
672-
FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
673-
Actions.ActOnFinishInlineFunctionDef(FD);
674665
}
675666

676667
/// ParseLexedMemberInitializers - We finished parsing the member specification

clang/test/Modules/try-func-body.cppm

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
2+
3+
export module func;
4+
class C {
5+
public:
6+
void member() try {
7+
8+
} catch (...) {
9+
10+
}
11+
};
12+
13+
// CHECK: define {{.*}}@_ZNW4func1C6memberEv

0 commit comments

Comments
 (0)