Skip to content

Commit e31cafb

Browse files
committed
feat(parse): recognize template specialization
1 parent 11fc88d commit e31cafb

File tree

6 files changed

+56
-7
lines changed

6 files changed

+56
-7
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
t: @struct <T: type> type < T> type = { }
2+
main: () = { }

regression-tests/test-results/clang-18/pure2-template-specialization.cpp.execution

Whitespace-only changes.

regression-tests/test-results/clang-18/pure2-template-specialization.cpp.output

Whitespace-only changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
#define CPP2_USE_MODULES Yes
3+
4+
//=== Cpp2 type declarations ====================================================
5+
6+
7+
#include "cpp2util.h"
8+
9+
#line 1 "pure2-template-specialization.cpp2"
10+
template<typename T> class t;
11+
12+
13+
//=== Cpp2 type definitions and function declarations ===========================
14+
15+
#line 1 "pure2-template-specialization.cpp2"
16+
template<typename T> class t {};
17+
auto main() -> int;
18+
19+
20+
//=== Cpp2 function definitions =================================================
21+
22+
23+
#line 2 "pure2-template-specialization.cpp2"
24+
auto main() -> int {}
25+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-template-specialization.cpp2... ok (all Cpp2, passes safety checks)
2+

source/parse.h

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,7 @@ struct declaration_node
23622362

23632363
std::vector<std::unique_ptr<id_expression_node>> meta_functions;
23642364
std::unique_ptr<parameter_declaration_list_node> template_parameters;
2365+
std::unique_ptr<unqualified_id_node> specialization_template_arguments;
23652366
source_position requires_pos = {};
23662367
std::unique_ptr<logical_or_expression_node> requires_clause_expression;
23672368

@@ -4982,6 +4983,7 @@ class parser
49824983
//G
49834984
//G template-argument-list:
49844985
//G template-argument-list ',' template-argument
4986+
//G template-argument
49854987
//G
49864988
//G template-argument:
49874989
//G # note: < > << >> are not allowed in expressions until new ( is opened
@@ -5031,20 +5033,20 @@ class parser
50315033
}
50325034
return expression(false); // false == disallow unparenthesized relational comparisons in template args
50335035
}()
5034-
)
5036+
)
50355037
{
50365038
term.arg = std::move(e);
50375039
}
5038-
5040+
50395041
// Else try parsing it as a type id
50405042
else if (auto i = type_id()) {
50415043
term.arg = std::move(i);
50425044
}
5043-
5045+
50445046
else {
50455047
break;
50465048
}
5047-
5049+
50485050
n->template_args.push_back( std::move(term) );
50495051
}
50505052
// Use the lambda trick to jam in a "next" clause
@@ -6452,9 +6454,9 @@ class parser
64526454

64536455
//G unnamed-declaration:
64546456
//G ':' meta-functions-list? template-parameter-declaration-list? function-type requires-clause? '=' statement
6455-
//G ':' meta-functions-list? template-parameter-declaration-list? type-id? requires-clause? '=' statement
6457+
//G ':' meta-functions-list? template-parameter-declaration-list? template-specialization-argument-list? type-id? requires-clause? '=' statement
64566458
//G ':' meta-functions-list? template-parameter-declaration-list? type-id
6457-
//G ':' meta-functions-list? template-parameter-declaration-list? 'final'? 'type' requires-clause? '=' statement
6459+
//G ':' meta-functions-list? template-parameter-declaration-list? template-specialization-argument-list? 'final'? 'type' requires-clause? '=' statement
64586460
//G ':' 'namespace' '=' statement
64596461
//G
64606462
//G meta-functions-list:
@@ -6465,7 +6467,10 @@ class parser
64656467
//G 'requires' logical-or-expression
64666468
//G
64676469
//G template-parameter-declaration-list
6468-
//G '<' parameter-declaration-seq '>'
6470+
//G '<' parameter-declaration-seq? '>'
6471+
//G
6472+
//G template-specialization-argument-list:
6473+
//G 'type' '<' template-argument-list '>'
64696474
//G
64706475
auto unnamed_declaration(
64716476
source_position start,
@@ -6602,6 +6607,21 @@ class parser
66026607
n->template_parameters = std::move(template_parameters);
66036608
}
66046609

6610+
// Next is an optional template specialization argument list
6611+
if (
6612+
curr() == "type"
6613+
&& peek(1)
6614+
&& peek(1)->type() == lexeme::Less
6615+
)
6616+
{
6617+
auto specialization_template_arguments = unqualified_id();
6618+
if (!specialization_template_arguments) {
6619+
error("invalid template specialization argument list");
6620+
return {};
6621+
}
6622+
n->specialization_template_arguments = std::move(specialization_template_arguments);
6623+
}
6624+
66056625
auto guard =
66066626
captures_allowed
66076627
? std::make_unique<capture_groups_stack_guard>(this, &n->captures)

0 commit comments

Comments
 (0)