Skip to content

Commit dd04703

Browse files
committed
Add *using-statement* - using declarations and using directives
I've been putting off adding these useful statements because I wanted to think longer about whether there was a way to improve on these, but nothing currently comes to mind so I'll provide them with their Cpp1 syntax for now This is a pretty good "model PR" for the places to touch when adding a new grammar production... In parse.h: - create the `*_node` type(s) that the grammar needs, and add them as alternatives in the existing node types that should reach them - add a `pretty_print_visualize` for them, and hook them up in the visualizers for the existing nodes that should reach them - add a `pretty_print_visualize` for them, and hook them up in the visualizers for the existing nodes that should reach them - add the parser function(s) (with //G grammar) to generate them, and hook them up in the parser functions (with //G grammar extensions) for the existing node types that should reach them - add overload(s) for the new node types to the parse tree debug visitor In cppfront.cpp: - add lowering function(s) for them, and hook them up in the lowering functions for the existing nodes that should reach them
1 parent 999179a commit dd04703

File tree

7 files changed

+156
-30
lines changed

7 files changed

+156
-30
lines changed

regression-tests/pure2-print.cpp2

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ outer: @print type = {
1010
protected f: () -> int = 42;
1111

1212
g: (virtual this, i:int) -> int = {
13+
using namespace ::std;
14+
1315
s := "string literal";
1416
ret: int = i;
1517
p: const * const int = ret&;
@@ -18,8 +20,8 @@ outer: @print type = {
1820
}
1921
ret += strlen(s) - 10 + s.strlen() * (16 / (3 & 2)) % 3;
2022

21-
m: std::map<const int,std::string> = ();
22-
m[0] = "har" as std::string;
23+
m: map<const int,string> = ();
24+
m[0] = "har" as string;
2325
ret -= h("x", m).length();
2426
_ = m;
2527

@@ -66,6 +68,9 @@ outer: @print type = {
6668
test: () = {
6769
namespace_alias: namespace == ::std;
6870

71+
using std::array;
72+
using std::cout;
73+
6974
type_alias: type == std::array<int,10>;
7075

7176
object_alias_1: i8 == 42;

regression-tests/test-results/pure2-print.cpp

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,17 @@ CPP2_REQUIRES_ (true)
3131
public: [[nodiscard]] virtual auto g(cpp2::in<int> i) const -> int;
3232

3333

34-
#line 29 "pure2-print.cpp2"
34+
#line 31 "pure2-print.cpp2"
3535
private: [[nodiscard]] static auto h(cpp2::in<std::string> s, std::map<int const,std::string>& m) -> std::string;
3636
struct values_ret { int offset; std::string name; };
3737

3838

3939

40-
#line 52 "pure2-print.cpp2"
40+
#line 54 "pure2-print.cpp2"
4141
public: template<typename T> [[nodiscard]] auto values([[maybe_unused]] T const& param2) const& -> values_ret;
4242

4343

44-
#line 57 "pure2-print.cpp2"
44+
#line 59 "pure2-print.cpp2"
4545
public: explicit mytype();
4646

4747
public: mytype([[maybe_unused]] mytype const& that);
@@ -50,38 +50,38 @@ CPP2_REQUIRES_ (true)
5050

5151
public: static auto variadic(auto const& ...x) -> void
5252
CPP2_REQUIRES_ ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...))
53-
#line 63 "pure2-print.cpp2"
53+
#line 65 "pure2-print.cpp2"
5454
;
5555
};
5656

5757
public: static auto test() -> void;
5858

5959

60-
#line 84 "pure2-print.cpp2"
60+
#line 89 "pure2-print.cpp2"
6161
public: template<typename ...Ts> class x {
6262
private: std::tuple<Ts...> tup {};
6363
public: x() = default;
6464
public: x(x const&) = delete; /* No 'that' constructor, suppress copy */
6565
public: auto operator=(x const&) -> void = delete;
6666

67-
#line 86 "pure2-print.cpp2"
67+
#line 91 "pure2-print.cpp2"
6868
};
6969

7070
public: template<typename ...Args> static auto print(std::ostream& out, Args const& ...args) -> void
7171
CPP2_REQUIRES_ (cpp2::cmp_greater_eq(sizeof(Args)...,0))
72-
#line 88 "pure2-print.cpp2"
72+
#line 93 "pure2-print.cpp2"
7373
;
7474

7575

76-
#line 92 "pure2-print.cpp2"
76+
#line 97 "pure2-print.cpp2"
7777
public: template<typename ...Args> [[nodiscard]] static auto all(Args const& ...args) -> bool;
7878

7979
public: outer() = default;
8080
public: outer(outer const&) = delete; /* No 'that' constructor, suppress copy */
8181
public: auto operator=(outer const&) -> void = delete;
8282

8383

84-
#line 95 "pure2-print.cpp2"
84+
#line 100 "pure2-print.cpp2"
8585
};
8686

8787
auto main() -> int;
@@ -100,6 +100,8 @@ requires (true)
100100
[[nodiscard]] auto outer::mytype::f() -> int { return 42; }
101101

102102
[[nodiscard]] auto outer::mytype::g(cpp2::in<int> i) const -> int{
103+
using namespace ::std;
104+
103105
auto s {"string literal"};
104106
int ret {i};
105107
int const* const p {&ret};
@@ -108,8 +110,8 @@ requires (true)
108110
}
109111
ret += strlen(s) - 10 + CPP2_UFCS_0(strlen, std::move(s)) * (16 / (3 & 2)) % 3;
110112

111-
std::map<int const,std::string> m {};
112-
cpp2::assert_in_bounds(m, 0) = cpp2::as_<std::string>("har");
113+
map<int const,string> m {};
114+
cpp2::assert_in_bounds(m, 0) = cpp2::as_<string>("har");
113115
ret -= CPP2_UFCS_0(length, h("x", m));
114116
static_cast<void>(std::move(m));
115117

@@ -118,11 +120,11 @@ requires (true)
118120

119121
[[nodiscard]] auto outer::mytype::h(cpp2::in<std::string> s, std::map<int const,std::string>& m) -> std::string
120122

121-
#line 32 "pure2-print.cpp2"
123+
#line 34 "pure2-print.cpp2"
122124
{
123125
cpp2::Default.expects(CPP2_UFCS_0(empty, m) == false || false, "");
124126
cpp2::Bounds.expects([_0 = 0, _1 = CPP2_UFCS_0(ssize, m), _2 = 100]{ return cpp2::cmp_less(_0,_1) && cpp2::cmp_less(_1,_2); }() && true != false, "");
125-
#line 33 "pure2-print.cpp2"
127+
#line 35 "pure2-print.cpp2"
126128
auto a {[]() -> void{}};
127129
auto b {[]() -> void{}};
128130
auto c {[]() -> void{}};
@@ -132,10 +134,10 @@ requires (true)
132134
do {} while ( CPP2_UFCS_0(empty, s) && [&]{ b() ; return true; }() );
133135

134136
for ( [[maybe_unused]] auto const& param1 : m ) {
135-
#line 41 "pure2-print.cpp2"
136-
{ do {goto CONTINUE_41_13; } while (false); c(); } CPP2_CONTINUE_BREAK(41_13) }
137-
138137
#line 43 "pure2-print.cpp2"
138+
{ do {goto CONTINUE_43_13; } while (false); c(); } CPP2_CONTINUE_BREAK(43_13) }
139+
140+
#line 45 "pure2-print.cpp2"
139141
if (cpp2::is(!(CPP2_UFCS_0(empty, s)), (true))) {std::move(a)(); }
140142
else {if (!(CPP2_UFCS_0(empty, m))) {std::move(b)(); }
141143
else {std::move(c)(); }}
@@ -148,7 +150,7 @@ requires (true)
148150
template<typename T> [[nodiscard]] auto outer::mytype::values([[maybe_unused]] T const& param2) const& -> values_ret{
149151
cpp2::deferred_init<int> offset;
150152
cpp2::deferred_init<std::string> name;
151-
#line 53 "pure2-print.cpp2"
153+
#line 55 "pure2-print.cpp2"
152154
offset.construct(53);
153155
name.construct("plugh");
154156
return { std::move(offset.value()), std::move(name.value()) }; }
@@ -161,19 +163,22 @@ requires (true)
161163

162164
auto outer::mytype::variadic(auto const& ...x) -> void
163165
requires ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...))
164-
#line 63 "pure2-print.cpp2"
166+
#line 65 "pure2-print.cpp2"
165167
{(std::cout << ... << x); }
166168

167-
#line 66 "pure2-print.cpp2"
169+
#line 68 "pure2-print.cpp2"
168170
auto outer::test() -> void{
169171
namespace namespace_alias = ::std;
170172

173+
using std::array;
174+
using std::cout;
175+
171176
using type_alias = std::array<int,10>;
172177

173178
cpp2::i8 constexpr object_alias_1 = 42;
174179
auto constexpr object_alias_2 = 42;
175180

176-
#line 75 "pure2-print.cpp2"
181+
#line 80 "pure2-print.cpp2"
177182
::outer::mytype var {};
178183
std::cout << CPP2_UFCS(g, var, 42) << "\n";
179184

@@ -183,18 +188,18 @@ requires ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...))
183188
() << "\n";
184189
}
185190

186-
#line 88 "pure2-print.cpp2"
191+
#line 93 "pure2-print.cpp2"
187192
template<typename ...Args> auto outer::print(std::ostream& out, Args const& ...args) -> void
188193
requires (cpp2::cmp_greater_eq(sizeof(Args)...,0))
189-
#line 88 "pure2-print.cpp2"
194+
#line 93 "pure2-print.cpp2"
190195
{
191196
(out << ... << args);
192197
}
193198

194199
template<typename ...Args> [[nodiscard]] auto outer::all(Args const& ...args) -> bool {
195200
return (... && args); }
196201

197-
#line 97 "pure2-print.cpp2"
202+
#line 102 "pure2-print.cpp2"
198203
auto main() -> int{
199204
outer::test();
200205
}

regression-tests/test-results/pure2-print.cpp2.output

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ outer: type =
1212
in i: int
1313
) -> move int =
1414
{
15+
using namespace ::std;
1516
s: = "string literal";
1617
ret: int = i;
1718
p: const * const int = ret&;
@@ -20,8 +21,8 @@ outer: type =
2021
ret = -p*;
2122
}
2223
ret += strlen(s) - 10 + s.strlen() * (16 / (3 & 2)) % 3;
23-
m: std::map<const int, std::string> = ();
24-
m[0] = "har" as std::string;
24+
m: map<const int, string> = ();
25+
m[0] = "har" as string;
2526
ret -= h("x", m).length();
2627
_ = m;
2728
return ret;
@@ -118,6 +119,8 @@ outer: type =
118119
test:() =
119120
{
120121
namespace_alias: namespace == ::std;
122+
using std::array;
123+
using std::cout;
121124
type_alias: type == std::array<int, 10>;
122125
object_alias_1: i8 == 42;
123126
object_alias_2: == 42;

regression-tests/test-results/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.2.1 Build 8A21:1522
2+
cppfront compiler v0.3.0 Build 8A21:1546
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

source/build.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"8A21:1522"
1+
"8A21:1546"

source/cppfront.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2420,6 +2420,22 @@ class cppfront
24202420
}
24212421

24222422

2423+
//-----------------------------------------------------------------------
2424+
//
2425+
auto emit(using_statement_node const& n)
2426+
-> void
2427+
{
2428+
assert(n.keyword);
2429+
emit(*n.keyword);
2430+
2431+
if (n.for_namespace) {
2432+
printer.print_cpp2(" namespace", n.position());
2433+
}
2434+
2435+
printer.print_cpp2(" " + print_to_string(*n.id) + ";", n.position());
2436+
}
2437+
2438+
24232439
//-----------------------------------------------------------------------
24242440
//
24252441
auto build_capture_lambda_intro_for(
@@ -3826,6 +3842,7 @@ class cppfront
38263842
try_emit<statement_node::declaration>(n.statement);
38273843
try_emit<statement_node::return_ >(n.statement);
38283844
try_emit<statement_node::iteration >(n.statement);
3845+
try_emit<statement_node::using_ >(n.statement);
38293846
try_emit<statement_node::contract >(n.statement);
38303847
try_emit<statement_node::inspect >(n.statement, false);
38313848
try_emit<statement_node::jump >(n.statement);

0 commit comments

Comments
 (0)