Skip to content

Commit 2892889

Browse files
committed
fix(to_cpp1): define static data member with placeholder type in class
1 parent 61550a5 commit 2892889

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
@@ -20,6 +20,16 @@ class myclass;
2020
template<typename T> class myclass2;
2121

2222

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

2535

@@ -60,6 +70,29 @@ template<typename T> class myclass2 {
6070
auto main() -> int;
6171

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

@@ -93,3 +126,10 @@ auto main() -> int{
93126
myfunc2();
94127
}
95128

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

source/to_cpp1.h

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

5083+
// Helper for aliases that emit as a defining declaration.
5084+
auto const type_scope_object_alias_emits_in_phase_1_only = [&]() {
5085+
assert(
5086+
n.parent_is_type()
5087+
&& n.is_object_alias()
5088+
);
5089+
return !a->type_id
5090+
|| a->type_id->is_wildcard();
5091+
};
5092+
50835093
// Namespace-scope aliases are emitted in phase 1,
5084-
// type-scope object aliases in both phases 1 and 2, and
5094+
// type-scope object aliases is emitted in phase 1 and maybe 2, and
50855095
// function-scope aliases in phase 2
50865096
if (
50875097
(
@@ -5093,6 +5103,7 @@ class cppfront
50935103
n.parent_is_type()
50945104
&& n.is_object_alias()
50955105
&& printer.get_phase() == printer.phase2_func_defs
5106+
&& !type_scope_object_alias_emits_in_phase_1_only()
50965107
)
50975108
||
50985109
(
@@ -5158,21 +5169,34 @@ class cppfront
51585169
// Handle object aliases:
51595170
// - at function scope, it's const&
51605171
// - at namespace scope, it's inline constexpr
5161-
// - at type scope, it's also inline constexpr but see note (*) below
5172+
// - at type scope, it's also static constexpr but see note (*) below
51625173
else if (a->is_object_alias())
51635174
{
51645175
auto type = std::string{"auto"};
51655176
if (a->type_id) {
51665177
type = print_to_string(*a->type_id);
51675178
}
51685179

5169-
// (*) If this is at type scope, Cpp1 requires an out-of-line declaration dance
5170-
// for some cases to work - see https://stackoverflow.com/questions/11928089/
51715180
if (n.parent_is_type())
51725181
{
51735182
assert (n.parent_declaration->name());
51745183

5175-
if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
5184+
if (type_scope_object_alias_emits_in_phase_1_only()) {
5185+
if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
5186+
printer.print_cpp2(
5187+
"static constexpr "
5188+
+ type + " "
5189+
+ print_to_string(*n.identifier)
5190+
+ " = "
5191+
+ print_to_string( *std::get<alias_node::an_object>(a->initializer) )
5192+
+ ";\n",
5193+
n.position()
5194+
);
5195+
}
5196+
}
5197+
// At type scope, Cpp1 requires an out-of-line declaration dance
5198+
// for some cases to work - see https://stackoverflow.com/questions/11928089/
5199+
else if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
51765200
printer.print_cpp2(
51775201
"static const "
51785202
+ type + " "

0 commit comments

Comments
 (0)