@@ -1255,7 +1255,7 @@ class cppfront
1255
1255
1256
1256
// Now we'll open the Cpp1 file
1257
1257
auto cpp1_filename = sourcefile.substr (0 , std::ssize (sourcefile) - 1 );
1258
-
1258
+
1259
1259
// Use explicit filename override if present,
1260
1260
// otherwise strip leading path
1261
1261
if (!flag_cpp1_filename.empty ()) {
@@ -3458,12 +3458,12 @@ class cppfront
3458
3458
last_was_prefixed = true ;
3459
3459
}
3460
3460
3461
- // Handle the other Cpp2 postfix operators that stay postfix in Cpp1
3461
+ // Handle the other Cpp2 postfix operators that stay postfix in Cpp1
3462
3462
// (currently '...' for expansion, not when used as a range operator)
3463
3463
else if (
3464
3464
is_postfix_operator (i->op ->type ())
3465
3465
&& !i->last_expr // not being used as a range operator
3466
- )
3466
+ )
3467
3467
{
3468
3468
flush_args ();
3469
3469
suffix.emplace_back ( i->op ->to_string (), i->op ->position ());
@@ -3504,7 +3504,7 @@ class cppfront
3504
3504
}
3505
3505
3506
3506
auto print = print_to_string (
3507
- *i->id_expr ,
3507
+ *i->id_expr ,
3508
3508
false , // not a local name
3509
3509
i->op ->type () == lexeme::Dot || i->op ->type () == lexeme::DotDot // member access
3510
3510
);
@@ -4453,8 +4453,8 @@ class cppfront
4453
4453
{
4454
4454
assert (n.declaration );
4455
4455
auto is_param_to_namespace_scope_type =
4456
- n.declaration ->parent_is_type ()
4457
- && n.declaration ->parent_declaration ->parent_is_namespace ()
4456
+ n.declaration ->parent_is_type ()
4457
+ && n.declaration ->parent_declaration ->parent_is_namespace ()
4458
4458
;
4459
4459
4460
4460
auto emit_in_phase_0 =
@@ -5091,7 +5091,7 @@ class cppfront
5091
5091
|| n.is_swap ()
5092
5092
|| n.is_destructor ()
5093
5093
|| (
5094
- n.my_decl
5094
+ n.my_decl
5095
5095
&& generating_move_from == n.my_decl
5096
5096
)
5097
5097
)
@@ -5105,7 +5105,7 @@ class cppfront
5105
5105
if (
5106
5106
n.is_assignment ()
5107
5107
|| (
5108
- n.my_decl
5108
+ n.my_decl
5109
5109
&& generating_assignment_from == n.my_decl
5110
5110
)
5111
5111
)
@@ -5776,8 +5776,18 @@ class cppfront
5776
5776
auto & a = std::get<declaration_node::an_alias>(n.type );
5777
5777
assert (a);
5778
5778
5779
+ // Helper for aliases that emit as a defining declaration.
5780
+ auto const type_scope_object_alias_emits_in_phase_1_only = [&]() {
5781
+ assert (
5782
+ n.parent_is_type ()
5783
+ && n.is_object_alias ()
5784
+ );
5785
+ return !a->type_id
5786
+ || a->type_id ->is_wildcard ();
5787
+ };
5788
+
5779
5789
// Namespace-scope aliases are emitted in phase 1,
5780
- // type-scope object aliases in both phases 1 and 2, and
5790
+ // type-scope object aliases is emitted in phase 1 and maybe 2, and
5781
5791
// function-scope aliases in phase 2
5782
5792
if (
5783
5793
(
@@ -5789,6 +5799,7 @@ class cppfront
5789
5799
n.parent_is_type ()
5790
5800
&& n.is_object_alias ()
5791
5801
&& printer.get_phase () == printer.phase2_func_defs
5802
+ && !type_scope_object_alias_emits_in_phase_1_only ()
5792
5803
)
5793
5804
||
5794
5805
(
@@ -5863,7 +5874,7 @@ class cppfront
5863
5874
// Handle object aliases:
5864
5875
// - at function scope, it's const&
5865
5876
// - at namespace scope, it's inline constexpr
5866
- // - at type scope, it's also inline constexpr but see note (*) below
5877
+ // - at type scope, it's also static constexpr but see note (*) below
5867
5878
else if (a->is_object_alias ())
5868
5879
{
5869
5880
auto type = std::string{" auto" };
@@ -5888,13 +5899,26 @@ class cppfront
5888
5899
}
5889
5900
};
5890
5901
5891
- // (*) If this is at type scope, Cpp1 requires an out-of-line declaration dance
5892
- // for some cases to work - see https://stackoverflow.com/questions/11928089/
5893
5902
if (n.parent_is_type ())
5894
5903
{
5895
5904
assert (n.parent_declaration ->name ());
5896
5905
5897
- if (printer.get_phase () == printer.phase1_type_defs_func_decls ) {
5906
+ if (type_scope_object_alias_emits_in_phase_1_only ()) {
5907
+ if (printer.get_phase () == printer.phase1_type_defs_func_decls ) {
5908
+ printer.print_cpp2 (
5909
+ " static constexpr "
5910
+ + type + " "
5911
+ + print_to_string (*n.identifier )
5912
+ + " = "
5913
+ + print_to_string ( *std::get<alias_node::an_object>(a->initializer ) )
5914
+ + " ;\n " ,
5915
+ n.position ()
5916
+ );
5917
+ }
5918
+ }
5919
+ // At type scope, Cpp1 requires an out-of-line declaration dance
5920
+ // for some cases to work - see https://stackoverflow.com/questions/11928089/
5921
+ else if (printer.get_phase () == printer.phase1_type_defs_func_decls ) {
5898
5922
printer.print_cpp2 (
5899
5923
" static const "
5900
5924
+ type + " "
@@ -6072,7 +6096,10 @@ class cppfront
6072
6096
6073
6097
// In class definitions, emit the explicit access specifier if there
6074
6098
// is one, or default to private for data and public for functions
6075
- if (printer.get_phase () == printer.phase1_type_defs_func_decls )
6099
+ if (
6100
+ printer.get_phase () == printer.phase1_type_defs_func_decls
6101
+ && n.identifier
6102
+ )
6076
6103
{
6077
6104
if (!n.is_default_access ()) {
6078
6105
assert (is_in_type);
@@ -6995,8 +7022,8 @@ class cppfront
6995
7022
return ;
6996
7023
}
6997
7024
}
6998
- printer.preempt_position_push (n.position ());
6999
- emit ( *type, {}, print_to_string (*n.identifier ) );
7025
+ printer.preempt_position_push (n.position ());
7026
+ emit ( *type, {}, print_to_string (*n.identifier ) );
7000
7027
printer.preempt_position_pop ();
7001
7028
7002
7029
if (
0 commit comments