Skip to content

Commit 9d86794

Browse files
committed
Generalize object aliases: make non-local ones static constexpr, and allow explicit types
1 parent 4e37486 commit 9d86794

File tree

5 files changed

+59
-48
lines changed

5 files changed

+59
-48
lines changed

regression-tests/test-results/pure2-bugfix-for-max-munch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//=== Cpp2 type definitions and function declarations ===========================
1212

1313
#line 1 "pure2-bugfix-for-max-munch.cpp2"
14-
template<typename T> auto const& v = 0;
14+
template<typename T> auto static constexpr v = 0;
1515
auto main() -> int;
1616

1717

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 8901:1703
2+
cppfront compiler v0.2.1 Build 8904:1014
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-
"8901:1703"
1+
"8904:1014"

source/cppfront.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,8 @@ class cppfront
15791579
|| n == "new"
15801580
|| n == "class"
15811581
|| n == "struct"
1582+
|| n == "enum"
1583+
|| n == "union"
15821584
)
15831585
{
15841586
printer.print_cpp2("cpp2_"+n.to_string(true), pos);
@@ -4969,9 +4971,27 @@ class cppfront
49694971
}
49704972

49714973
// Handle object aliases
4972-
else if (a->is_object_alias()) {
4974+
else if (a->is_object_alias())
4975+
{
4976+
auto intro = std::string{};
4977+
if (n.parent_is_function()) {
4978+
intro = "const&";
4979+
}
4980+
else if (n.parent_is_namespace() || n.parent_is_type()) {
4981+
intro = "static constexpr";
4982+
}
4983+
else {
4984+
assert(!"ICE: should be unreachable - an alias' parent should be a function, namespace, or type");
4985+
}
4986+
4987+
auto type = std::string{"auto"};
4988+
if (a->type_id) {
4989+
type = print_to_string(*a->type_id);
4990+
}
4991+
49734992
printer.print_cpp2(
4974-
"auto const& "
4993+
type + " "
4994+
+ intro + " "
49754995
+ print_to_string(*n.identifier)
49764996
+ " = "
49774997
+ print_to_string( *std::get<alias_node::an_object>(a->initializer) )

source/parse.h

Lines changed: 34 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,7 @@ struct namespace_node
22842284
struct alias_node
22852285
{
22862286
token const* type = {};
2287+
std::unique_ptr<type_id_node> type_id; // for objects
22872288

22882289
enum active : std::uint8_t { a_type, a_namespace, an_object };
22892290
std::variant<
@@ -2373,8 +2374,6 @@ struct declaration_node
23732374
// Attributes currently configurable only via metafunction API,
23742375
// not directly in the base language grammar
23752376
bool member_function_generation = true;
2376-
bool is_constexpr = false;
2377-
bool is_static = false;
23782377

23792378
// Constructor
23802379
//
@@ -2405,24 +2404,13 @@ struct declaration_node
24052404
member_function_generation = false;
24062405
}
24072406

2408-
auto make_constexpr()
2409-
-> void
2410-
{
2411-
is_constexpr = true;
2412-
}
2413-
2414-
auto make_static()
2415-
-> void
2416-
{
2417-
is_static = true;
2418-
}
2419-
24202407
auto object_type() const
24212408
-> std::string
24222409
{
24232410
if (!is_object()) {
24242411
return "(*ERROR*) not an object";
24252412
}
2413+
// Else
24262414
return std::get<an_object>(type)->to_string();
24272415
}
24282416

@@ -2432,7 +2420,11 @@ struct declaration_node
24322420
if (!is_object()) {
24332421
return "(*ERROR*) not an object";
24342422
}
2435-
return initializer->to_string();
2423+
else if (initializer) {
2424+
return initializer->to_string();
2425+
}
2426+
// Else
2427+
return "";
24362428
}
24372429

24382430
auto get_parent() const
@@ -6915,7 +6907,7 @@ class parser
69156907
//G alias
69166908
//G ':' template-parameter-declaration-list? 'type' '==' type-id ';'
69176909
//G ':' 'namespace' '==' qualified-id ';'
6918-
//G ':' template-parameter-declaration-list? '_'? '==' expression ';'
6910+
//G ':' template-parameter-declaration-list? type-id? '==' expression ';'
69196911
//G
69206912
//GT ':' function-type '==' expression ';'
69216913
//GT # See commit 63efa6ed21c4d4f4f136a7a73e9f6b2c110c81d7 comment
@@ -6944,35 +6936,34 @@ class parser
69446936
n->template_parameters = std::move(template_parameters);
69456937
}
69466938

6947-
if (
6948-
curr() != "type"
6949-
&& curr() != "namespace"
6950-
&& curr() != "_"
6951-
&& curr().type() != lexeme::EqualComparison
6952-
)
6939+
auto a = std::make_unique<alias_node>( &curr() );
6940+
6941+
// Next must be 'type', 'namespace', a type-id, or we're at the '=='
6942+
if (curr() == "type")
69536943
{
6954-
pos = start_pos; // backtrack
6955-
return {};
6944+
next();
69566945
}
6957-
6958-
// Pause parsing to check for some semantic diagnostics
6959-
6960-
if (
6961-
n->template_parameters
6962-
&& curr() == "namespace"
6963-
)
6946+
else if (curr() == "namespace")
69646947
{
6965-
errors.emplace_back(
6966-
curr().position(),
6967-
"a namespace cannot have template parameters"
6968-
);
6969-
return {};
6948+
next();
6949+
if (n->template_parameters) {
6950+
errors.emplace_back(
6951+
curr().position(),
6952+
"a namespace or namespace alias cannot have template parameters"
6953+
);
6954+
return {};
6955+
}
6956+
}
6957+
else if (curr().type() != lexeme::EqualComparison)
6958+
{
6959+
a->type_id = type_id();
6960+
if (!a->type_id) {
6961+
pos = start_pos; // backtrack
6962+
return {};
6963+
}
69706964
}
69716965

6972-
// Resume parsing
6973-
6974-
auto a = std::make_unique<alias_node>( &curr() );
6975-
next();
6966+
// Now we should be at the '==' if this is an alias
69766967

69776968
if (curr().type() == lexeme::EqualComparison) {
69786969
next();
@@ -6987,12 +6978,12 @@ class parser
69876978

69886979
if (
69896980
n->parent_is_type()
6990-
&& *a->type != "type"
6981+
&& *a->type == "namespace"
69916982
)
69926983
{
69936984
errors.emplace_back(
69946985
curr().position(),
6995-
"only a type alias may appear in a type scope - not a namespace or object alias"
6986+
"a namespace alias cannot appear in a type scope"
69966987
);
69976988
return {};
69986989
}
@@ -7040,7 +7031,7 @@ class parser
70407031

70417032
// Object alias
70427033
else if (
7043-
*a->type == "_"
7034+
a->type_id
70447035
|| a->type->type() == lexeme::EqualComparison
70457036
)
70467037
{

0 commit comments

Comments
 (0)