@@ -362,7 +362,6 @@ auto prefix_expression_node::visit(auto& v, int depth) -> void
362
362
363
363
struct unqualified_id_node
364
364
{
365
- token const * const_qualifier = {}; // optional
366
365
token const * identifier = {}; // required
367
366
368
367
enum active { empty=0 , expression, id_expression };
@@ -398,9 +397,6 @@ struct unqualified_id_node
398
397
auto visit (auto & v, int depth) -> void
399
398
{
400
399
v.start (*this , depth);
401
- if (const_qualifier) {
402
- v.start (*const_qualifier, depth+1 );
403
- }
404
400
assert (identifier);
405
401
v.start (*identifier, depth+1 );
406
402
@@ -454,6 +450,44 @@ struct qualified_id_node
454
450
}
455
451
};
456
452
453
+ struct type_id_node
454
+ {
455
+ source_position pos;
456
+
457
+ token const * const_qualifier = {}; // optional
458
+
459
+ enum active { empty=0 , qualified, unqualified };
460
+ std::variant<
461
+ std::monostate,
462
+ std::unique_ptr<qualified_id_node>,
463
+ std::unique_ptr<unqualified_id_node>
464
+ > id;
465
+
466
+ auto get_token () -> token const * {
467
+ if (id.index () == unqualified) {
468
+ return std::get<unqualified>(id)->get_token ();
469
+ }
470
+ // else
471
+ return {};
472
+ }
473
+
474
+ auto position () const -> source_position
475
+ {
476
+ return pos;
477
+ }
478
+
479
+ auto visit (auto & v, int depth) -> void
480
+ {
481
+ v.start (*this , depth);
482
+ if (const_qualifier) {
483
+ v.start (*const_qualifier, depth+1 );
484
+ }
485
+ try_visit<qualified >(id, v, depth);
486
+ try_visit<unqualified>(id, v, depth);
487
+ v.end (*this , depth);
488
+ }
489
+ };
490
+
457
491
struct id_expression_node
458
492
{
459
493
source_position pos;
@@ -622,7 +656,7 @@ struct inspect_expression_node
622
656
bool is_constexpr = false ;
623
657
token const * identifier;
624
658
std::unique_ptr<expression_node> expression;
625
- std::unique_ptr<id_expression_node> result_type;
659
+ std::unique_ptr<type_id_node> result_type;
626
660
source_position open_brace;
627
661
source_position close_brace;
628
662
@@ -851,7 +885,7 @@ struct declaration_node
851
885
enum active { function, object };
852
886
std::variant<
853
887
std::unique_ptr<function_type_node>,
854
- std::unique_ptr<id_expression_node >
888
+ std::unique_ptr<type_id_node >
855
889
> type;
856
890
857
891
source_position equal_sign = {};
@@ -1752,9 +1786,38 @@ class parser
1752
1786
}
1753
1787
1754
1788
1789
+ // G type-id:
1790
+ // G const-opt unqualified-id
1791
+ // G const-opt qualified-id
1792
+ // G
1793
+ auto type_id () -> std::unique_ptr<type_id_node>
1794
+ {
1795
+ auto n = std::make_unique<type_id_node>();
1796
+
1797
+ if (curr ().type () == lexeme::Keyword && curr () == " const" ) {
1798
+ n->const_qualifier = &curr ();
1799
+ next ();
1800
+ }
1801
+
1802
+ if (auto id = qualified_id ()) {
1803
+ n->pos = id->position ();
1804
+ n->id = std::move (id);
1805
+ assert (n->id .index () == id_expression_node::qualified);
1806
+ return n;
1807
+ }
1808
+ if (auto id = unqualified_id ()) {
1809
+ n->pos = id->position ();
1810
+ n->id = std::move (id);
1811
+ assert (n->id .index () == id_expression_node::unqualified);
1812
+ return n;
1813
+ }
1814
+ return {};
1815
+ }
1816
+
1817
+
1755
1818
// G unqualified-id:
1756
- // G const-opt identifier
1757
- // G const-opt template-id
1819
+ // G identifier
1820
+ // G template-id
1758
1821
// GTODO operator-function-id
1759
1822
// G
1760
1823
// G template-id:
@@ -1778,11 +1841,6 @@ class parser
1778
1841
1779
1842
auto n = std::make_unique<unqualified_id_node>();
1780
1843
1781
- if (curr ().type () == lexeme::Keyword && curr () == " const" ) {
1782
- n->const_qualifier = &curr ();
1783
- next ();
1784
- }
1785
-
1786
1844
n->identifier = &curr ();
1787
1845
next ();
1788
1846
@@ -2262,7 +2320,7 @@ class parser
2262
2320
2263
2321
// G inspect-expression:
2264
2322
// G inspect constexpr-opt expression { alternative-seq-opt }
2265
- // G inspect constexpr-opt expression -> id-expression { alternative-seq-opt }
2323
+ // G inspect constexpr-opt expression -> type-id { alternative-seq-opt }
2266
2324
// G
2267
2325
// G alternative-seq:
2268
2326
// G alternative
@@ -2312,12 +2370,12 @@ class parser
2312
2370
return {};
2313
2371
}
2314
2372
2315
- auto id = id_expression ();
2316
- if (!id ) {
2373
+ auto type = type_id ();
2374
+ if (!type ) {
2317
2375
error (" expected a valid inspect return type after ->" );
2318
2376
return {};
2319
2377
}
2320
- n->result_type = std::move (id );
2378
+ n->result_type = std::move (type );
2321
2379
}
2322
2380
else if (is_expression) {
2323
2381
error (" an inspect expression must have an explicit '-> result_type'" );
@@ -2778,8 +2836,8 @@ class parser
2778
2836
2779
2837
// G unnamed-declaration:
2780
2838
// G : function-type = statement
2781
- // G : id-expression -opt = statement
2782
- // G : id-expression
2839
+ // G : type-id -opt = statement
2840
+ // G : type-id
2783
2841
// G
2784
2842
auto unnamed_declaration (source_position pos, bool semicolon_required = true , bool captures_allowed = false ) -> std::unique_ptr<declaration_node>
2785
2843
{
@@ -2814,22 +2872,22 @@ class parser
2814
2872
else if (curr ().type () == lexeme::Multiply) {
2815
2873
n->pointer_declarator = &curr ();
2816
2874
next ();
2817
- if (auto t = id_expression ()) {
2875
+ if (auto t = type_id ()) {
2818
2876
n->type = std::move (t);
2819
2877
assert (n->type .index () == declaration_node::object);
2820
2878
}
2821
2879
}
2822
2880
2823
2881
// Or just a type, declaring a non-pointer object
2824
- else if (auto t = id_expression ()) {
2882
+ else if (auto t = type_id ()) {
2825
2883
n->type = std::move (t);
2826
2884
assert (n->type .index () == declaration_node::object);
2827
2885
}
2828
2886
2829
2887
// Or nothing, declaring an object of deduced type,
2830
- // which we'll represent using an empty id-expression
2888
+ // which we'll represent using an empty type-id
2831
2889
else {
2832
- n->type = std::make_unique<id_expression_node >();
2890
+ n->type = std::make_unique<type_id_node >();
2833
2891
assert (n->type .index () == declaration_node::object);
2834
2892
deduced_type = true ;
2835
2893
}
@@ -3059,6 +3117,11 @@ class parse_tree_printer : printing_visitor
3059
3117
o << pre (indent) << " qualified-id\n " ;
3060
3118
}
3061
3119
3120
+ auto start (type_id_node const & n, int indent) -> void
3121
+ {
3122
+ o << pre (indent) << " type-id\n " ;
3123
+ }
3124
+
3062
3125
auto start (id_expression_node const & n, int indent) -> void
3063
3126
{
3064
3127
o << pre (indent) << " id-expression\n " ;
0 commit comments