ソースを参照

fix: parse explicit destructor calls with template arguments

The destructor-id in an explicit destructor call may name a class template
specialization, e.g. `p->~vector<int>()` or `p->~shared_ptr<const T>()`.
`destructor_name` only allowed `~ identifier`, so any template-id after `~`
produced an ERROR node. Allow an optional `template_argument_list` and add a
GLR conflict for `destructor_name` to resolve the `<` (template-args vs
less-than) ambiguity. A plain `~Name` is unchanged.
pull/360/head
Niclas 1ヶ月前
コミット
223c16bdb9
2個のファイルの変更58行の追加1行の削除
  1. +2
    -1
      grammar.js
  2. +56
    -0
      test/corpus/expressions.txt

+ 2
- 1
grammar.js ファイルの表示

@ -105,6 +105,7 @@ module.exports = grammar(C, {
[$.qualified_field_identifier, $.template_method, $.template_type],
[$.type_specifier, $.template_type, $.template_function, $.expression],
[$.splice_type_specifier, $.splice_expression],
[$.destructor_name],
],
inline: ($, original) => original.concat([
@ -1379,7 +1380,7 @@ module.exports = grammar(C, {
')',
),
destructor_name: $ => prec(1, seq('~', $.identifier)),
destructor_name: $ => prec(1, seq('~', $.identifier, optional($.template_argument_list))),
compound_literal_expression: ($, original) => choice(
original,

+ 56
- 0
test/corpus/expressions.txt ファイルの表示

@ -1723,3 +1723,59 @@ template void negateValues(Args... args) {
(identifier)))
(string_literal
(string_content))))))))))
================================================================================
Explicit destructor calls with template arguments
================================================================================
int main() {
a->~Baz<int>();
b.~Qux<int, float>();
c->~Box<vector<int>>();
}
--------------------------------------------------------------------------------
(translation_unit
(function_definition
(primitive_type)
(function_declarator
(identifier)
(parameter_list))
(compound_statement
(expression_statement
(call_expression
(field_expression
(identifier)
(destructor_name
(identifier)
(template_argument_list
(type_descriptor
(primitive_type)))))
(argument_list)))
(expression_statement
(call_expression
(field_expression
(identifier)
(destructor_name
(identifier)
(template_argument_list
(type_descriptor
(primitive_type))
(type_descriptor
(primitive_type)))))
(argument_list)))
(expression_statement
(call_expression
(field_expression
(identifier)
(destructor_name
(identifier)
(template_argument_list
(type_descriptor
(template_type
(type_identifier)
(template_argument_list
(type_descriptor
(primitive_type))))))))
(argument_list))))))

読み込み中…
キャンセル
保存