From 32fd5522eb63e69d2f925eb9fabc5d6ca997a536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Mon, 25 Sep 2023 18:34:13 -0400 Subject: [PATCH 1/5] test: add case for templated type-scope object alias --- .../pure2-type-and-namespace-aliases.cpp2 | 4 ++++ .../pure2-type-and-namespace-aliases.cpp.output | 3 +++ .../pure2-type-and-namespace-aliases.cpp | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/regression-tests/pure2-type-and-namespace-aliases.cpp2 b/regression-tests/pure2-type-and-namespace-aliases.cpp2 index c50daaa5f..a02dc54f5 100644 --- a/regression-tests/pure2-type-and-namespace-aliases.cpp2 +++ b/regression-tests/pure2-type-and-namespace-aliases.cpp2 @@ -23,6 +23,10 @@ myfunc: () = { std::cout << "(s)$\n"; } +myclass2: type = { + value: int == 42; +} + main: () = { view: type == std::string_view; N4: namespace == std::literals; diff --git a/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output b/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output index e69de29bb..bb7deb3ef 100644 --- a/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output +++ b/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output @@ -0,0 +1,3 @@ +pure2-type-and-namespace-aliases.cpp2:27:26: error: ‘template class myclass2’ used without template arguments + 27 | value: int == 42; + | ^ diff --git a/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp b/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp index da0294f32..f83553e49 100644 --- a/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp +++ b/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp @@ -16,6 +16,10 @@ namespace N { class myclass; +#line 26 "pure2-type-and-namespace-aliases.cpp2" +template class myclass2; + + //=== Cpp2 type definitions and function declarations =========================== @@ -44,6 +48,15 @@ auto myfunc() -> void; #line 26 "pure2-type-and-namespace-aliases.cpp2" +template class myclass2 { + public: static const int value; + + public: myclass2() = default; + public: myclass2(myclass2 const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(myclass2 const&) -> void = delete; +#line 28 "pure2-type-and-namespace-aliases.cpp2" +}; + auto main() -> int; @@ -65,6 +78,10 @@ auto myfunc() -> void{ std::cout << cpp2::to_string(s) + "\n"; } +#line 27 "pure2-type-and-namespace-aliases.cpp2" + inline constexpr int myclass2::value = 42; + +#line 30 "pure2-type-and-namespace-aliases.cpp2" auto main() -> int{ using view = std::string_view; namespace N4 = std::literals; From 97c74c12d4f14b8b3b2feaa6947b3a91e8841b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Mon, 25 Sep 2023 19:08:44 -0400 Subject: [PATCH 2/5] fix(cpp1): emit parents' *template-head*s of alias --- ...r-non-local-function-expression.cpp.output | 2 + ...ure2-type-and-namespace-aliases.cpp.output | 3 - .../pure2-type-and-namespace-aliases.cpp | 2 +- source/cppfront.cpp | 87 +++++++------------ 4 files changed, 32 insertions(+), 62 deletions(-) diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output index 2e0819f63..2572f4371 100644 --- a/regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output +++ b/regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output @@ -1 +1,3 @@ pure2-bugfix-for-non-local-function-expression.cpp2:9:7: warning: ‘t’ has a base ‘t::’ which has no linkage [-Wsubobject-linkage] + 9 | t: @struct type = { + | ^ diff --git a/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output b/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output index bb7deb3ef..e69de29bb 100644 --- a/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output +++ b/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output @@ -1,3 +0,0 @@ -pure2-type-and-namespace-aliases.cpp2:27:26: error: ‘template class myclass2’ used without template arguments - 27 | value: int == 42; - | ^ diff --git a/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp b/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp index f83553e49..76df5a049 100644 --- a/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp +++ b/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp @@ -79,7 +79,7 @@ auto myfunc() -> void{ } #line 27 "pure2-type-and-namespace-aliases.cpp2" - inline constexpr int myclass2::value = 42; + template inline CPP2_CONSTEXPR int myclass2::value = 42; #line 30 "pure2-type-and-namespace-aliases.cpp2" auto main() -> int{ diff --git a/source/cppfront.cpp b/source/cppfront.cpp index 34e8a410f..33773d1c9 100644 --- a/source/cppfront.cpp +++ b/source/cppfront.cpp @@ -4904,6 +4904,30 @@ class cppfront ) -> void { + // Helper for declarations with parent *template-head*s. + auto const emit_parent_template_parameters = [&]() { + auto parent_template_parameters = std::string{}; + auto parent = n.parent_declaration; + while ( + parent + && parent->is_type() + ) + { + if (parent->requires_clause_expression) { + parent_template_parameters = + "requires( " + print_to_string(*parent->requires_clause_expression) + " )\n" + + parent_template_parameters; + } + if (parent->template_parameters) { + parent_template_parameters = + "template " + print_to_string( *parent->template_parameters, false, true ) + + " " + parent_template_parameters; + } + parent = parent->parent_declaration; + } + printer.print_cpp2(parent_template_parameters, n.position()); + }; + // Helper for declarations that can have requires-clauses auto const emit_requires_clause = [&]() { if ( @@ -5097,46 +5121,12 @@ class cppfront return; } - auto parent_template_params = std::string{}; - auto parent_template_args = std::string{}; - auto parent_qualifier = std::string{}; - - auto parent = n.parent_declaration; - while (parent && parent->is_type()) - { - if (!parent_qualifier.empty()) { - parent_qualifier.insert(0, "::"); - } - parent_qualifier.insert(0, parent->name()->to_string()); - - if (parent->template_parameters) { - parent_template_params.insert(0, "template" + print_to_string(*parent->template_parameters)); - for (auto const& param : parent->template_parameters->parameters) { - assert(param->name()); - if (parent_template_args.empty()) { - parent_template_args = "<>"; - } - else { - parent_template_args.insert(parent_template_args.size()-1, ","); - } - parent_template_args.insert(parent_template_args.size()-1, param->name()->as_string_view()); - } - } - - parent = parent->parent_declaration; - } - - if (!parent_template_params.empty()) { - parent_template_params += " "; - } - + emit_parent_template_parameters(); printer.print_cpp2( - parent_template_params - + "inline CPP2_CONSTEXPR " + "inline CPP2_CONSTEXPR " + type - + parent_template_args - + " " + parent_qualifier - + parent_template_args + "::" + + " " + + type_qualification_if_any_for(n) + print_to_string(*n.identifier) + " = " + print_to_string( *std::get(a->initializer) ) @@ -5304,26 +5294,7 @@ class cppfront && n.initializer // only if the function has a definition (is not abstract) ) { - auto parent_template_parameters = std::string{}; - auto parent = n.parent_declaration; - while ( - parent - && parent->is_type() - ) - { - if (parent->requires_clause_expression) { - parent_template_parameters = - "requires( " + print_to_string(*parent->requires_clause_expression) + " )\n" - + parent_template_parameters; - } - if (parent->template_parameters) { - parent_template_parameters = - "template " + print_to_string( *parent->template_parameters, false, true ) - + " " + parent_template_parameters; - } - parent = parent->parent_declaration; - } - printer.print_cpp2(parent_template_parameters, n.position()); + emit_parent_template_parameters(); } // Now, emit our own template parameters From 2ccd72a89438e2aff0adebe973ee9e02cd5e57f7 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Sat, 21 Oct 2023 15:15:57 -0700 Subject: [PATCH 3/5] Delete regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output Signed-off-by: Herb Sutter --- .../pure2-bugfix-for-non-local-function-expression.cpp.output | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output deleted file mode 100644 index 2572f4371..000000000 --- a/regression-tests/test-results/gcc-13/pure2-bugfix-for-non-local-function-expression.cpp.output +++ /dev/null @@ -1,3 +0,0 @@ -pure2-bugfix-for-non-local-function-expression.cpp2:9:7: warning: ‘t’ has a base ‘t::’ which has no linkage [-Wsubobject-linkage] - 9 | t: @struct type = { - | ^ From a5006e797e6faa7b458aa4b4f457c7982ea34cc8 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Sat, 21 Oct 2023 15:19:25 -0700 Subject: [PATCH 4/5] Update pure2-type-and-namespace-aliases.cpp2 Signed-off-by: Herb Sutter --- regression-tests/pure2-type-and-namespace-aliases.cpp2 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/regression-tests/pure2-type-and-namespace-aliases.cpp2 b/regression-tests/pure2-type-and-namespace-aliases.cpp2 index a02dc54f5..c50daaa5f 100644 --- a/regression-tests/pure2-type-and-namespace-aliases.cpp2 +++ b/regression-tests/pure2-type-and-namespace-aliases.cpp2 @@ -23,10 +23,6 @@ myfunc: () = { std::cout << "(s)$\n"; } -myclass2: type = { - value: int == 42; -} - main: () = { view: type == std::string_view; N4: namespace == std::literals; From 52f2d7cd99aac2b3c09aae6de989f4c44cf72f65 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Sat, 21 Oct 2023 15:20:31 -0700 Subject: [PATCH 5/5] Update pure2-type-and-namespace-aliases.cpp Signed-off-by: Herb Sutter --- .../pure2-type-and-namespace-aliases.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp b/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp index 76df5a049..da0294f32 100644 --- a/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp +++ b/regression-tests/test-results/pure2-type-and-namespace-aliases.cpp @@ -16,10 +16,6 @@ namespace N { class myclass; -#line 26 "pure2-type-and-namespace-aliases.cpp2" -template class myclass2; - - //=== Cpp2 type definitions and function declarations =========================== @@ -48,15 +44,6 @@ auto myfunc() -> void; #line 26 "pure2-type-and-namespace-aliases.cpp2" -template class myclass2 { - public: static const int value; - - public: myclass2() = default; - public: myclass2(myclass2 const&) = delete; /* No 'that' constructor, suppress copy */ - public: auto operator=(myclass2 const&) -> void = delete; -#line 28 "pure2-type-and-namespace-aliases.cpp2" -}; - auto main() -> int; @@ -78,10 +65,6 @@ auto myfunc() -> void{ std::cout << cpp2::to_string(s) + "\n"; } -#line 27 "pure2-type-and-namespace-aliases.cpp2" - template inline CPP2_CONSTEXPR int myclass2::value = 42; - -#line 30 "pure2-type-and-namespace-aliases.cpp2" auto main() -> int{ using view = std::string_view; namespace N4 = std::literals;