Skip to content

Commit 8f10de3

Browse files
usiemsmrbean-bremen
authored andcommitted
Better handling of variadic templates
1 parent a5f20ab commit 8f10de3

2 files changed

Lines changed: 23 additions & 9 deletions

File tree

generator/parser/ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,7 @@ struct TemplateArgumentAST: public AST
750750

751751
TypeIdAST *type_id{};
752752
ExpressionAST *expression{};
753+
bool variadic{};
753754
};
754755

755756
struct TemplateDeclarationAST: public DeclarationAST

generator/parser/parser.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
400400
while (true)
401401
{
402402
UnqualifiedNameAST *n = 0;
403-
if (!parseUnqualifiedName(n))
403+
if (!parseUnqualifiedName(n, acceptTemplateId))
404404
return false;
405405

406406
if (token_stream.lookAhead() == Token_scope)
@@ -419,12 +419,6 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
419419
else
420420
{
421421
Q_ASSERT(n != 0);
422-
if (!acceptTemplateId)
423-
{
424-
rewind(n->start_token);
425-
parseUnqualifiedName(n, false);
426-
}
427-
428422
ast->unqualified_name = n;
429423
break;
430424
}
@@ -1102,7 +1096,7 @@ bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
11021096
{
11031097
ast->type_id = 0;
11041098
rewind(saved);
1105-
parseUnaryExpression(ast->expression);
1099+
parseConditionalExpression(ast->expression);
11061100
}
11071101
ADVANCE(')', ")");
11081102
}
@@ -1187,6 +1181,7 @@ bool Parser::parseTemplateArgument(TemplateArgumentAST *&node)
11871181
ExpressionAST *expr = 0;
11881182

11891183
if (!parseTypeId(typeId) || (token_stream.lookAhead() != ','
1184+
&& token_stream.lookAhead() != Token_ellipsis
11901185
&& token_stream.lookAhead() != '>'
11911186
&& token_stream.lookAhead() != Token_shift_right))
11921187
{
@@ -1200,6 +1195,11 @@ bool Parser::parseTemplateArgument(TemplateArgumentAST *&node)
12001195
ast->type_id = typeId;
12011196
ast->expression = expr;
12021197

1198+
if (token_stream.lookAhead() == Token_ellipsis) {
1199+
nextToken();
1200+
ast->variadic = true;
1201+
}
1202+
12031203
UPDATE_POS(ast, start, token_stream.cursor());
12041204
node = ast;
12051205

@@ -3642,6 +3642,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
36423642
parseStringLiteral(ast->literal);
36433643
break;
36443644

3645+
case Token_ellipsis: // "..." can occur in constexpr of variadic templates
36453646
case Token_number_literal:
36463647
case Token_char_literal:
36473648
case Token_true:
@@ -3669,7 +3670,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
36693670
break;
36703671

36713672
default:
3672-
if (!parseName(ast->name))
3673+
if (!parseName(ast->name, true)) // this can also be a template
36733674
return false;
36743675

36753676
break;
@@ -3943,6 +3944,12 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node)
39433944
else
39443945
node = expr;
39453946

3947+
if (token_stream.lookAhead() == Token_ellipsis) {
3948+
// ignore ellipsis, it might be something like "Pair<Args1, Args2>...", which might appear
3949+
// in template arguments of variadic templates
3950+
nextToken();
3951+
}
3952+
39463953
return true;
39473954
}
39483955

@@ -3982,6 +3989,12 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
39823989
std::size_t sizeof_token = token_stream.cursor();
39833990
nextToken();
39843991

3992+
if (token_stream.lookAhead() == Token_ellipsis) {
3993+
// sizeof... is used on parameter packs - currently we ignore this
3994+
// todo: handle this
3995+
nextToken();
3996+
}
3997+
39853998
SizeofExpressionAST *ast = CreateNode<SizeofExpressionAST>(_M_pool);
39863999
ast->sizeof_token = sizeof_token;
39874000

0 commit comments

Comments
 (0)