Skip to content

Commit 79984ff

Browse files
committed
fix(to_cpp1): define static data member with placeholder type in class
1 parent 05ce45a commit 79984ff

File tree

4 files changed

+89
-5
lines changed

4 files changed

+89
-5
lines changed

regression-tests/pure2-type-and-namespace-aliases.cpp2

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,21 @@ main: () = {
3333
myfunc2 :== myfunc;
3434
myfunc2();
3535
}
36+
37+
myclass5: type == myclass4;
38+
39+
myclass3: @struct type = {
40+
v0 :== :std::array = (0);;
41+
v1 :== v0; // OK: Also uses the Cpp2 placeholder type.
42+
v2: myclass3 == myclass3(); // OK: Doesn't use the Cpp2 placeholder type.
43+
v3: _ == v0;
44+
v4: myclass3 == v2; // OK: Doesn't use the Cpp2 placeholder type.
45+
v5: myclass4 == myclass4(); // OK: Doesn't use the Cpp2 placeholder type.
46+
v6: myclass5 == myclass5(); // OK: Doesn't use the Cpp2 placeholder type.
47+
}
48+
49+
myclass4: @struct type = { }
50+
51+
myclass6: @struct <T: type> type = {
52+
v: <U> _ requires true == 0;
53+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
pure2-bugfix-for-non-local-function-expression.cpp2:9:7: warning: ‘t’ has a base ‘t::<lambda()>’ which has no linkage [-Wsubobject-linkage]
2+
9 | t: @struct type = {
3+
| ^

regression-tests/test-results/pure2-type-and-namespace-aliases.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ class myclass;
2121
template<typename T> class myclass2;
2222

2323

24+
#line 39 "pure2-type-and-namespace-aliases.cpp2"
25+
class myclass3;
26+
27+
28+
#line 49 "pure2-type-and-namespace-aliases.cpp2"
29+
class myclass4;
30+
31+
template<typename T> class myclass6;
32+
33+
2434
//=== Cpp2 type definitions and function declarations ===========================
2535

2636
#line 1 "pure2-type-and-namespace-aliases.cpp2"
@@ -60,6 +70,29 @@ template<typename T> class myclass2 {
6070

6171
auto main() -> int;
6272

73+
#line 37 "pure2-type-and-namespace-aliases.cpp2"
74+
using myclass5 = myclass4;
75+
76+
class myclass3 {
77+
public: static constexpr auto v0 = std::array{0};
78+
public: static constexpr auto v1 = v0;// OK: Also uses the Cpp2 placeholder type.
79+
public: static const myclass3 v2;// OK: Doesn't use the Cpp2 placeholder type.
80+
public: static constexpr auto v3 = v0;
81+
public: static const myclass3 v4;// OK: Doesn't use the Cpp2 placeholder type.
82+
public: static const myclass4 v5;// OK: Doesn't use the Cpp2 placeholder type.
83+
public: static const myclass5 v6;// OK: Doesn't use the Cpp2 placeholder type.
84+
};
85+
86+
class myclass4 {};
87+
88+
template<typename T> class myclass6 {
89+
public: template<typename U>
90+
CPP2_REQUIRES_ (true)
91+
#line 52 "pure2-type-and-namespace-aliases.cpp2"
92+
static constexpr auto v = 0;
93+
};
94+
95+
6396
//=== Cpp2 function definitions =================================================
6497

6598
#line 1 "pure2-type-and-namespace-aliases.cpp2"
@@ -94,3 +127,10 @@ auto main() -> int{
94127
myfunc2();
95128
}
96129

130+
#line 42 "pure2-type-and-namespace-aliases.cpp2"
131+
inline CPP2_CONSTEXPR myclass3 myclass3::v2 = myclass3();
132+
133+
inline CPP2_CONSTEXPR myclass3 myclass3::v4 = v2;
134+
inline CPP2_CONSTEXPR myclass4 myclass3::v5 = myclass4();
135+
inline CPP2_CONSTEXPR myclass5 myclass3::v6 = myclass5();
136+

source/to_cpp1.h

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5351,8 +5351,18 @@ class cppfront
53515351
auto& a = std::get<declaration_node::an_alias>(n.type);
53525352
assert(a);
53535353

5354+
// Helper for aliases that emit as a defining declaration.
5355+
auto const type_scope_object_alias_emits_in_phase_1_only = [&]() {
5356+
assert(
5357+
n.parent_is_type()
5358+
&& n.is_object_alias()
5359+
);
5360+
return !a->type_id
5361+
|| a->type_id->is_wildcard();
5362+
};
5363+
53545364
// Namespace-scope aliases are emitted in phase 1,
5355-
// type-scope object aliases in both phases 1 and 2, and
5365+
// type-scope object aliases is emitted in phase 1 and maybe 2, and
53565366
// function-scope aliases in phase 2
53575367
if (
53585368
(
@@ -5364,6 +5374,7 @@ class cppfront
53645374
n.parent_is_type()
53655375
&& n.is_object_alias()
53665376
&& printer.get_phase() == printer.phase2_func_defs
5377+
&& !type_scope_object_alias_emits_in_phase_1_only()
53675378
)
53685379
||
53695380
(
@@ -5438,21 +5449,34 @@ class cppfront
54385449
// Handle object aliases:
54395450
// - at function scope, it's const&
54405451
// - at namespace scope, it's inline constexpr
5441-
// - at type scope, it's also inline constexpr but see note (*) below
5452+
// - at type scope, it's also static constexpr but see note (*) below
54425453
else if (a->is_object_alias())
54435454
{
54445455
auto type = std::string{"auto"};
54455456
if (a->type_id) {
54465457
type = print_to_string(*a->type_id);
54475458
}
54485459

5449-
// (*) If this is at type scope, Cpp1 requires an out-of-line declaration dance
5450-
// for some cases to work - see https://stackoverflow.com/questions/11928089/
54515460
if (n.parent_is_type())
54525461
{
54535462
assert (n.parent_declaration->name());
54545463

5455-
if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
5464+
if (type_scope_object_alias_emits_in_phase_1_only()) {
5465+
if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
5466+
printer.print_cpp2(
5467+
"static constexpr "
5468+
+ type + " "
5469+
+ print_to_string(*n.identifier)
5470+
+ " = "
5471+
+ print_to_string( *std::get<alias_node::an_object>(a->initializer) )
5472+
+ ";\n",
5473+
n.position()
5474+
);
5475+
}
5476+
}
5477+
// At type scope, Cpp1 requires an out-of-line declaration dance
5478+
// for some cases to work - see https://stackoverflow.com/questions/11928089/
5479+
else if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
54565480
printer.print_cpp2(
54575481
"static const "
54585482
+ type + " "

0 commit comments

Comments
 (0)