@@ -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 ()) {
@@ -3428,12 +3428,12 @@ class cppfront
3428
3428
last_was_prefixed = true ;
3429
3429
}
3430
3430
3431
- // Handle the other Cpp2 postfix operators that stay postfix in Cpp1
3431
+ // Handle the other Cpp2 postfix operators that stay postfix in Cpp1
3432
3432
// (currently '...' for expansion, not when used as a range operator)
3433
3433
else if (
3434
3434
is_postfix_operator (i->op ->type ())
3435
3435
&& !i->last_expr // not being used as a range operator
3436
- )
3436
+ )
3437
3437
{
3438
3438
flush_args ();
3439
3439
suffix.emplace_back ( i->op ->to_string (), i->op ->position ());
@@ -3474,7 +3474,7 @@ class cppfront
3474
3474
}
3475
3475
3476
3476
auto print = print_to_string (
3477
- *i->id_expr ,
3477
+ *i->id_expr ,
3478
3478
false , // not a local name
3479
3479
i->op ->type () == lexeme::Dot || i->op ->type () == lexeme::DotDot // member access
3480
3480
);
@@ -4406,8 +4406,8 @@ class cppfront
4406
4406
{
4407
4407
assert (n.declaration );
4408
4408
auto is_param_to_namespace_scope_type =
4409
- n.declaration ->parent_is_type ()
4410
- && n.declaration ->parent_declaration ->parent_is_namespace ()
4409
+ n.declaration ->parent_is_type ()
4410
+ && n.declaration ->parent_declaration ->parent_is_namespace ()
4411
4411
;
4412
4412
4413
4413
auto emit_in_phase_0 =
@@ -5033,7 +5033,7 @@ class cppfront
5033
5033
|| n.is_swap ()
5034
5034
|| n.is_destructor ()
5035
5035
|| (
5036
- n.my_decl
5036
+ n.my_decl
5037
5037
&& generating_move_from == n.my_decl
5038
5038
)
5039
5039
)
@@ -5047,7 +5047,7 @@ class cppfront
5047
5047
if (
5048
5048
n.is_assignment ()
5049
5049
|| (
5050
- n.my_decl
5050
+ n.my_decl
5051
5051
&& generating_assignment_from == n.my_decl
5052
5052
)
5053
5053
)
@@ -5718,8 +5718,18 @@ class cppfront
5718
5718
auto & a = std::get<declaration_node::an_alias>(n.type );
5719
5719
assert (a);
5720
5720
5721
+ // Helper for aliases that emit as a defining declaration.
5722
+ auto const type_scope_object_alias_emits_in_phase_1_only = [&]() {
5723
+ assert (
5724
+ n.parent_is_type ()
5725
+ && n.is_object_alias ()
5726
+ );
5727
+ return !a->type_id
5728
+ || a->type_id ->is_wildcard ();
5729
+ };
5730
+
5721
5731
// Namespace-scope aliases are emitted in phase 1,
5722
- // type-scope object aliases in both phases 1 and 2, and
5732
+ // type-scope object aliases is emitted in phase 1 and maybe 2, and
5723
5733
// function-scope aliases in phase 2
5724
5734
if (
5725
5735
(
@@ -5731,6 +5741,7 @@ class cppfront
5731
5741
n.parent_is_type ()
5732
5742
&& n.is_object_alias ()
5733
5743
&& printer.get_phase () == printer.phase2_func_defs
5744
+ && !type_scope_object_alias_emits_in_phase_1_only ()
5734
5745
)
5735
5746
||
5736
5747
(
@@ -5805,7 +5816,7 @@ class cppfront
5805
5816
// Handle object aliases:
5806
5817
// - at function scope, it's const&
5807
5818
// - at namespace scope, it's inline constexpr
5808
- // - at type scope, it's also inline constexpr but see note (*) below
5819
+ // - at type scope, it's also static constexpr but see note (*) below
5809
5820
else if (a->is_object_alias ())
5810
5821
{
5811
5822
auto type = std::string{" auto" };
@@ -5830,13 +5841,26 @@ class cppfront
5830
5841
}
5831
5842
};
5832
5843
5833
- // (*) If this is at type scope, Cpp1 requires an out-of-line declaration dance
5834
- // for some cases to work - see https://stackoverflow.com/questions/11928089/
5835
5844
if (n.parent_is_type ())
5836
5845
{
5837
5846
assert (n.parent_declaration ->name ());
5838
5847
5839
- if (printer.get_phase () == printer.phase1_type_defs_func_decls ) {
5848
+ if (type_scope_object_alias_emits_in_phase_1_only ()) {
5849
+ if (printer.get_phase () == printer.phase1_type_defs_func_decls ) {
5850
+ printer.print_cpp2 (
5851
+ " static constexpr "
5852
+ + type + " "
5853
+ + print_to_string (*n.identifier )
5854
+ + " = "
5855
+ + print_to_string ( *std::get<alias_node::an_object>(a->initializer ) )
5856
+ + " ;\n " ,
5857
+ n.position ()
5858
+ );
5859
+ }
5860
+ }
5861
+ // At type scope, Cpp1 requires an out-of-line declaration dance
5862
+ // for some cases to work - see https://stackoverflow.com/questions/11928089/
5863
+ else if (printer.get_phase () == printer.phase1_type_defs_func_decls ) {
5840
5864
printer.print_cpp2 (
5841
5865
" static const "
5842
5866
+ type + " "
@@ -6014,7 +6038,10 @@ class cppfront
6014
6038
6015
6039
// In class definitions, emit the explicit access specifier if there
6016
6040
// is one, or default to private for data and public for functions
6017
- if (printer.get_phase () == printer.phase1_type_defs_func_decls )
6041
+ if (
6042
+ printer.get_phase () == printer.phase1_type_defs_func_decls
6043
+ && n.identifier
6044
+ )
6018
6045
{
6019
6046
if (!n.is_default_access ()) {
6020
6047
assert (is_in_type);
@@ -6935,8 +6962,8 @@ class cppfront
6935
6962
return ;
6936
6963
}
6937
6964
}
6938
- printer.preempt_position_push (n.position ());
6939
- emit ( *type, {}, print_to_string (*n.identifier ) );
6965
+ printer.preempt_position_push (n.position ());
6966
+ emit ( *type, {}, print_to_string (*n.identifier ) );
6940
6967
printer.preempt_position_pop ();
6941
6968
6942
6969
if (
0 commit comments