diff --git a/include/cpp2regex.h b/include/cpp2regex.h index 27b4f2b9b3..6ce453dafd 100644 --- a/include/cpp2regex.h +++ b/include/cpp2regex.h @@ -3,6 +3,32 @@ #define CPP2REGEX_H_CPP2 +//=== Cpp1 type definitions and function declarations ==================================================== + +#line 1 "cpp2regex.h2" + +// Copyright 2022-2024 Herb Sutter +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Part of the Cppfront Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://github.com/hsutter/cppfront/blob/main/LICENSE for license information. + + +//=========================================================================== +// Regex support +//=========================================================================== + +#ifndef CPP2_CPP2REGEX_H +#define CPP2_CPP2REGEX_H + +template +using matcher_wrapper_type = typename matcher_wrapper::template wrap; + +template +using matcher_context_type = typename matcher::context; +#line 758 "cpp2regex.h2" +#endif + //=== Cpp2 type declarations ==================================================== @@ -15,6 +41,9 @@ namespace cpp2 { namespace regex { +template using bstring = std::basic_string; +template using bview = std::basic_string_view; + #line 38 "cpp2regex.h2" template class match_group; @@ -54,12 +83,59 @@ template class negated_class_entry; #line 211 "cpp2regex.h2" template class shorthand_class_entry; +#line 220 "cpp2regex.h2" +template using digits_class = named_class_entry>; +template using lower_class = named_class_entry>; +template using upper_class = named_class_entry>; + +#line 226 "cpp2regex.h2" +template using alnum_class = named_class_entry,upper_class,digits_class>>; +template using alpha_class = named_class_entry,upper_class>>; +template using ascii_class = named_class_entry>; +template using blank_class = named_class_entry>; +template using cntrl_class = named_class_entry,single_class_entry>>; +template using graph_class = named_class_entry>; +template using hor_space_class = named_class_entry>; +template using print_class = named_class_entry>; +template using punct_class = named_class_entry','?','@','[','\\',']','^','_','`','{','|','}','~',']'>>; +template using space_class = named_class_entry>; +template using ver_space_class = named_class_entry>; +template using word_class = named_class_entry,single_class_entry>>; +template using xdigit_class = named_class_entry,range_class_entry,digits_class>>; + +#line 242 "cpp2regex.h2" +template using short_digits_class = shorthand_class_entry>; +template using short_hor_space_class = shorthand_class_entry>; +template using short_space_class = shorthand_class_entry>; +template using short_vert_space_class = shorthand_class_entry>; +template using short_word_class = shorthand_class_entry>; + +template using short_not_digits_class = negated_class_entry>>; +template using short_not_hor_space_class = negated_class_entry>>; +template using short_not_space_class = negated_class_entry>>; +template using short_not_vert_space_class = negated_class_entry>>; +template using short_not_word_class = negated_class_entry>>; + #line 259 "cpp2regex.h2" template class alternative_token_matcher; #line 337 "cpp2regex.h2" template class class_token_matcher; +#line 397 "cpp2regex.h2" +template using named_class_no_new_line = class_token_matcher>; +template using named_class_digits = class_token_matcher>; +template using named_class_hor_space = class_token_matcher>; +template using named_class_space = class_token_matcher>; +template using named_class_ver_space = class_token_matcher>; +template using named_class_word = class_token_matcher>; + +template using named_class_not_digits = class_token_matcher>; +template using named_class_not_hor_space = class_token_matcher>; +template using named_class_not_space = class_token_matcher>; +template using named_class_not_ver_space = class_token_matcher>; +template using named_class_not_word = class_token_matcher>; + #line 492 "cpp2regex.h2" class range_flags; @@ -79,34 +155,12 @@ template class regular_expression; #line 1 "cpp2regex.h2" -// Copyright 2022-2024 Herb Sutter -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// Part of the Cppfront Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://github.com/hsutter/cppfront/blob/main/LICENSE for license information. - - -//=========================================================================== -// Regex support -//=========================================================================== - -#ifndef CPP2_CPP2REGEX_H -#define CPP2_CPP2REGEX_H - -template -using matcher_wrapper_type = typename matcher_wrapper::template wrap; - -template -using matcher_context_type = typename matcher::context; - #line 22 "cpp2regex.h2" namespace cpp2 { namespace regex { -template using bstring = std::basic_string; -template using bview = std::basic_string_view; - +#line 29 "cpp2regex.h2" //----------------------------------------------------------------------- // // Helper structures for the expression matching. @@ -335,39 +389,14 @@ template class s #line 218 "cpp2regex.h2" // Named basic character classes // -template using digits_class = named_class_entry>; -template using lower_class = named_class_entry>; -template using upper_class = named_class_entry>; +#line 224 "cpp2regex.h2" // Named other classes // -template using alnum_class = named_class_entry,upper_class,digits_class>>; -template using alpha_class = named_class_entry,upper_class>>; -template using ascii_class = named_class_entry>; -template using blank_class = named_class_entry>; -template using cntrl_class = named_class_entry,single_class_entry>>; -template using graph_class = named_class_entry>; -template using hor_space_class = named_class_entry>; -template using print_class = named_class_entry>; -template using punct_class = named_class_entry','?','@','[','\\',']','^','_','`','{','|','}','~',']'>>; -template using space_class = named_class_entry>; -template using ver_space_class = named_class_entry>; -template using word_class = named_class_entry,single_class_entry>>; -template using xdigit_class = named_class_entry,range_class_entry,digits_class>>; +#line 240 "cpp2regex.h2" // Shorthand class entries // -template using short_digits_class = shorthand_class_entry>; -template using short_hor_space_class = shorthand_class_entry>; -template using short_space_class = shorthand_class_entry>; -template using short_vert_space_class = shorthand_class_entry>; -template using short_word_class = shorthand_class_entry>; - -template using short_not_digits_class = negated_class_entry>>; -template using short_not_hor_space_class = negated_class_entry>>; -template using short_not_space_class = negated_class_entry>>; -template using short_not_vert_space_class = negated_class_entry>>; -template using short_not_word_class = negated_class_entry>>; #line 255 "cpp2regex.h2" // Regex syntax: | Example: ab|ba @@ -459,18 +488,6 @@ template c #line 395 "cpp2regex.h2" // Named short classes // -template using named_class_no_new_line = class_token_matcher>; -template using named_class_digits = class_token_matcher>; -template using named_class_hor_space = class_token_matcher>; -template using named_class_space = class_token_matcher>; -template using named_class_ver_space = class_token_matcher>; -template using named_class_word = class_token_matcher>; - -template using named_class_not_digits = class_token_matcher>; -template using named_class_not_hor_space = class_token_matcher>; -template using named_class_not_space = class_token_matcher>; -template using named_class_not_ver_space = class_token_matcher>; -template using named_class_not_word = class_token_matcher>; #line 411 "cpp2regex.h2" // Regex syntax: \ Example: \1 @@ -624,7 +641,6 @@ template class regular_expression } } -#endif //=== Cpp2 function definitions ================================================= diff --git a/source/reflect.h b/source/reflect.h index aa9a4962af..290f6bb1c5 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -3,6 +3,25 @@ #define REFLECT_H_CPP2 +//=== Cpp1 type definitions and function declarations ==================================================== + +#line 1 "reflect.h2" + +// Copyright 2022-2024 Herb Sutter +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Part of the Cppfront Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://github.com/hsutter/cppfront/blob/main/LICENSE for license information. + + +//=========================================================================== +// Reflection and meta +//=========================================================================== + +#include "parse.h" +#include "cpp2regex.h" +using namespace cpp2::regex; + //=== Cpp2 type declarations ==================================================== @@ -45,12 +64,19 @@ class compound_statement; #line 1094 "reflect.h2" class value_member_info; +#line 1608 "reflect.h2" +using error_func = std::function x)>; + #line 1612 "reflect.h2" class expression_flags; #line 1628 "reflect.h2" class regex_token; +#line 1648 "reflect.h2" +using token_ptr = std::shared_ptr; +using token_vec = std::vector; + #line 1654 "reflect.h2" class regex_token_check; @@ -122,21 +148,6 @@ template class regex_generator; #line 1 "reflect.h2" -// Copyright 2022-2024 Herb Sutter -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// Part of the Cppfront Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://github.com/hsutter/cppfront/blob/main/LICENSE for license information. - - -//=========================================================================== -// Reflection and meta -//=========================================================================== - -#include "parse.h" -#include "cpp2regex.h" -using namespace cpp2::regex; - #line 17 "reflect.h2" namespace cpp2 { @@ -602,9 +613,6 @@ auto cpp2_union(meta::type_declaration& t) -> void; #line 1588 "reflect.h2" auto print(cpp2::impl::in t) -> void; -#line 1608 "reflect.h2" -using error_func = std::function x)>; - #line 1612 "reflect.h2" class expression_flags { @@ -667,9 +675,6 @@ class regex_token #line 1646 "reflect.h2" }; -using token_ptr = std::shared_ptr; -using token_vec = std::vector; - #line 1652 "reflect.h2" // Adds a check in code generation. // diff --git a/source/to_cpp1.h b/source/to_cpp1.h index 2c2ffeece6..cc4332c9ad 100644 --- a/source/to_cpp1.h +++ b/source/to_cpp1.h @@ -1341,6 +1341,75 @@ class cppfront auto map_iter = tokens.get_map().cbegin(); auto hpp_includes = std::string{}; + //--------------------------------------------------------------------- + // Do cpp1 type declaration and function declarations + printer.print_extra( "\n//=== Cpp1 type definitions and function declarations ====================================================\n\n" ); + printer.reset_line_to(1, true); + for ( + lineno_t curr_lineno = 0; + auto const& line : source.get_lines() + ) + { + // Skip dummy line we added to make 0-vs-1-based offsets readable + if (curr_lineno != 0) + { + // If it's a Cpp1 line, emit it + if (line.cat != source_line::category::cpp2) + { + if ( + source.has_cpp2() + && line.cat != source_line::category::preprocessor + ) + { + ++ret.cpp2_lines; + } + else + { + ++ret.cpp1_lines; + } + + if ( + flag_cpp2_only + && !line.text.empty() + && line.cat != source_line::category::comment + && line.cat != source_line::category::import + ) + { + if (line.cat == source_line::category::preprocessor) { + if (!line.text.ends_with(".h2\"")) { + errors.emplace_back( + source_position(curr_lineno, 1), + "pure-cpp2 switch disables the preprocessor, including #include (except of .h2 files) - use import instead (note: 'import std;' is implicit in -pure-cpp2)" + ); + return {}; + } + } + else { + errors.emplace_back( + source_position(curr_lineno, 1), + "pure-cpp2 switch disables Cpp1 syntax" + ); + return {}; + } + } + + if ( + line.cat == source_line::category::preprocessor + && line.text.ends_with(".h2\"") + ) + { + // Strip off the 2" + auto h_include = line.text.substr(0, line.text.size()-2); + printer.print_cpp1( h_include + "\"", curr_lineno ); + hpp_includes += h_include + "pp\"\n"; + } + else { + printer.print_cpp1( line.text, curr_lineno ); + } + } + } + ++curr_lineno; + } //--------------------------------------------------------------------- // Do phase0_type_decls @@ -1408,63 +1477,9 @@ class cppfront // Skip dummy line we added to make 0-vs-1-based offsets readable if (curr_lineno != 0) { - // If it's a Cpp1 line, emit it - if (line.cat != source_line::category::cpp2) + // If it's a Cpp2 line, emit it + if (line.cat == source_line::category::cpp2) { - if ( - source.has_cpp2() - && line.cat != source_line::category::preprocessor - ) - { - ++ret.cpp2_lines; - } - else - { - ++ret.cpp1_lines; - } - - if ( - flag_cpp2_only - && !line.text.empty() - && line.cat != source_line::category::comment - && line.cat != source_line::category::import - ) - { - if (line.cat == source_line::category::preprocessor) { - if (!line.text.ends_with(".h2\"")) { - errors.emplace_back( - source_position(curr_lineno, 1), - "pure-cpp2 switch disables the preprocessor, including #include (except of .h2 files) - use import instead (note: 'import std;' is implicit in -pure-cpp2)" - ); - return {}; - } - } - else { - errors.emplace_back( - source_position(curr_lineno, 1), - "pure-cpp2 switch disables Cpp1 syntax" - ); - return {}; - } - } - - if ( - line.cat == source_line::category::preprocessor - && line.text.ends_with(".h2\"") - ) - { - // Strip off the 2" - auto h_include = line.text.substr(0, line.text.size()-2); - printer.print_cpp1( h_include + "\"", curr_lineno ); - hpp_includes += h_include + "pp\"\n"; - } - else { - printer.print_cpp1( line.text, curr_lineno ); - } - } - - // If it's a Cpp2 line... - else { ++ret.cpp2_lines; // We should be in a position to emit a set of Cpp2 declarations @@ -5767,16 +5782,16 @@ class cppfront return; } - // In phase 0, only need to consider namespaces and types + // In phase 0, only need to consider namespaces, types, and Namespace-scope alias + const auto processNode = [&]() -> bool { + if (printer.get_phase() != printer.phase0_type_decls) return true; + if (n.is_namespace()) return true; + if (n.is_type()) return true; + if (n.is_alias() && n.parent_is_namespace()) return true; + return false; + }; - if ( - printer.get_phase() == printer.phase0_type_decls - && !n.is_namespace() - && !n.is_type() - ) - { - return; - } + if (!processNode()) return; // If this is a generated declaration (negative source line number), // add a line break before @@ -5800,26 +5815,26 @@ class cppfront auto& a = std::get(n.type); assert(a); - // Namespace-scope aliases are emitted in phase 1, + // Namespace-scope aliases are emitted in phase 0, // type-scope object aliases in both phases 1 and 2, and // function-scope aliases in phase 2 - if ( - ( - !n.parent_is_function() - && printer.get_phase() == printer.phase1_type_defs_func_decls - ) - || - ( - n.parent_is_type() - && n.is_object_alias() - && printer.get_phase() == printer.phase2_func_defs - ) - || - ( - n.parent_is_function() - && printer.get_phase() == printer.phase2_func_defs - ) - ) + const auto processAliasNode = [&]() -> bool { + if (!n.parent_is_function()) { + if (n.parent_is_namespace()) { + if (printer.get_phase() == printer.phase0_type_decls) return true; + } else { + if (printer.get_phase() == printer.phase1_type_defs_func_decls) return true; + } + } + if (n.parent_is_type() && n.is_object_alias()) { + if (printer.get_phase() == printer.phase2_func_defs) return true; + } + if (n.parent_is_function()) { + if (printer.get_phase() == printer.phase2_func_defs) return true; + } + return false; + }; + if (processAliasNode()) { assert( a->is_type_alias() @@ -6137,23 +6152,28 @@ class cppfront } // Now, emit our own template parameters - if ( - n.template_parameters - && ( - printer.get_phase() < printer.phase2_func_defs - || n.is_object() - || ( - n.is_function() - && n.has_name() // only if it is not unnamed function aka lambda - && n.initializer // only if the function has a definition (is not abstract) - && printer.get_phase() == printer.phase2_func_defs - ) - ) - && ( - !n.is_concept() - || printer.get_phase() == printer.phase1_type_defs_func_decls - ) - ) + const auto processTemplateParameters = [&]() -> bool { + if (!n.template_parameters) return false; + const auto rule1 = [&]() -> bool { + if (printer.get_phase() < printer.phase2_func_defs) return true; + if (n.is_object()) return true; + if (!n.is_function()) return false; + if (!n.has_name()) return false; // only if it is not unnamed function aka lambda + if (!n.initializer) return false; // only if the function has a definition (is not abstract) + return printer.get_phase() == printer.phase2_func_defs; + }; + const auto rule2 = [&]() -> bool { + if (!n.is_concept()) return true; + return printer.get_phase() == printer.phase1_type_defs_func_decls; + }; + const auto rule3 = [&]() -> bool { + if (!n.is_alias()) return true; + if (!n.parent_is_namespace()) return true; + return printer.get_phase() == printer.phase0_type_decls; + }; + return rule1() && rule2() && rule3(); + }; + if (processTemplateParameters()) { printer.print_cpp2("template", n.position()); emit(*n.template_parameters, false, true);