From e79fecbef1e55b3cda2e6e82d776a53d6494e144 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Wed, 2 Jun 2021 23:17:43 +0300 Subject: [PATCH 1/3] Provide fresh DetachedCaptures for each nested fragment like CXXFragmentParseRAII does with PendingUnquotes --- clang/include/clang/Sema/Sema.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5d45f4e2ed7b..ecabfd298474 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12497,16 +12497,20 @@ class Sema final { class CXXFragmentScopeRAII { Sema &S; bool PreviouslyInFragment; + SmallVector OriginalDetachedCaptures; public: CXXFragmentScopeRAII(Sema &S) - : S(S), PreviouslyInFragment(S.FragmentScope) { + : S(S), PreviouslyInFragment(S.FragmentScope), + OriginalDetachedCaptures() { S.FragmentScope = true; + OriginalDetachedCaptures.swap(S.DetachedCaptures); } ~CXXFragmentScopeRAII() { S.FragmentScope = PreviouslyInFragment; assert(S.DetachedCaptures.empty() && "captures left unattached"); + OriginalDetachedCaptures.swap(S.DetachedCaptures); } }; From 2445bc8479642af79702c1b237c24fdca0e9b4fb Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Thu, 3 Jun 2021 00:38:31 +0300 Subject: [PATCH 2/3] Add a test --- .../meta/nested_fragment_with_captions.cpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 clang/test/CXX/meta/nested_fragment_with_captions.cpp diff --git a/clang/test/CXX/meta/nested_fragment_with_captions.cpp b/clang/test/CXX/meta/nested_fragment_with_captions.cpp new file mode 100644 index 000000000000..ad5317c4d7be --- /dev/null +++ b/clang/test/CXX/meta/nested_fragment_with_captions.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -freflection -std=c++2a %s + +#define assert(E) if (!(E)) __builtin_abort(); + +namespace meta { + using info = decltype(^void); +} + +struct Member { + const char* name; + meta::info type; +}; + +constexpr Member members[]{ + Member{"a", ^int}, + Member{"b", ^int} +}; + +consteval void generate_struct(const char* name) { + -> fragment namespace { + struct [# %{name} #] { + consteval { + for (auto member : %{members}) { + -> fragment struct { + typename [: %{member.type} :] [# %{member.name} #]; + }; + } + } + }; + }; +} + +consteval { + generate_struct("S"); +} + +int main() { + S s{1, 2}; + assert(s.a == 1); + assert(s.b == 2); + return 0; +} \ No newline at end of file From 6d19d1b762507d18467c1c19251b512032a5a3be Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Thu, 3 Jun 2021 00:52:24 +0300 Subject: [PATCH 3/3] Rename test --- ...agment_with_captions.cpp => nested_fragment_with_captures.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clang/test/CXX/meta/{nested_fragment_with_captions.cpp => nested_fragment_with_captures.cpp} (100%) diff --git a/clang/test/CXX/meta/nested_fragment_with_captions.cpp b/clang/test/CXX/meta/nested_fragment_with_captures.cpp similarity index 100% rename from clang/test/CXX/meta/nested_fragment_with_captions.cpp rename to clang/test/CXX/meta/nested_fragment_with_captures.cpp