Skip to content

fix: parse explicit destructor calls with template-ids and qualified names#360

Open
edge90 wants to merge 2 commits into
tree-sitter:masterfrom
edge90:fix/templated-destructor-name
Open

fix: parse explicit destructor calls with template-ids and qualified names#360
edge90 wants to merge 2 commits into
tree-sitter:masterfrom
edge90:fix/templated-destructor-name

Conversation

@edge90

@edge90 edge90 commented Jun 8, 2026

Copy link
Copy Markdown

Two related fixes for explicit destructor calls (p->~T()) that produce ERROR nodes on valid C++. A destructor-id may name a class template specialization (a simple-template-id after ~), which is valid since C++98 (g++ -std=c++98 -pedantic-errors accepts the syntax; the std:: types in the examples are just C++11 library):

1. Template-id destructor-name. destructor_name only allowed ~ identifier, so a destructor naming a class template specialization failed to parse:

p->~vector<int>();
p->~shared_ptr<const Response>();

Fix: allow an optional template_argument_list, with a conflicts entry for destructor_name so the parser explores both readings of the < (template arguments vs. less-than); the trailing () disambiguates.

2. Qualified destructor calls. qualified_identifier already accepts a trailing destructor_name, but qualified_field_identifier (the -> / . member-access path) did not:

p->A::~A();
p->std::vector<int>::~vector();
p->A<int>::~A<int>();

Fix: add destructor_name to qualified_field_identifier, mirroring qualified_identifier.

A plain ~Name is unchanged. Corpus tests are added in test/corpus/expressions.txt and the full tree-sitter test suite passes.

edge90 added 2 commits June 8, 2026 20:42
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.
A qualified destructor-id in an explicit destructor call via `->`/`.`, e.g.
`p->std::vector<int>::~vector()` or `p->A::~A()`, produced an ERROR node.
`qualified_identifier` already accepts a trailing `destructor_name`, but
`qualified_field_identifier` (the member-access path) did not; mirror it there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant