From 15542dd7f88965ab414b7d53b6f2867bc7b895f1 Mon Sep 17 00:00:00 2001 From: "Kyle D. Kavanagh" Date: Mon, 14 Jul 2025 19:20:35 -0500 Subject: [PATCH 1/2] Correctly mark has_typename. Fixes #123 --- cxxheaderparser/parser.py | 3 ++- tests/test_template.py | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index 6314a4b..14caae9 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -607,8 +607,9 @@ def _parse_template_decl(self) -> TemplateDecl: lex.return_token(ptok) param = self._parse_template_type_parameter(tok, None) else: + lex.return_token(ptok) param, _ = self._parse_parameter( - ptok, + tok, TemplateNonTypeParam, concept_ok=False, deduce_this_ok=False, diff --git a/tests/test_template.py b/tests/test_template.py index 2a13b66..6995697 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -281,7 +281,8 @@ def test_template_dependent_nontype_default() -> None: segments=[ NameSpecifier(name="T"), NameSpecifier(name="type"), - ] + ], + has_typename=True, ) ), name="n", @@ -1098,7 +1099,7 @@ class concat_iterator void_t()).*std::declval())(std::declval()...))>> : std::true_type {}; - template + template struct S : public T... {}; """ data = parse_string(content, cleandoc=True) @@ -1636,12 +1637,9 @@ class concat_iterator ], template=TemplateDecl( params=[ - TemplateNonTypeParam( - type=Type( - typename=PQName( - segments=[NameSpecifier(name="T")] - ) - ), + TemplateTypeParam( + typekey="typename", + name="T", param_pack=True, ) ] From 6fc9fa1fb11b7c895d3d6d40e17acd61626bbd8f Mon Sep 17 00:00:00 2001 From: Dustin Spicuzza Date: Tue, 15 Jul 2025 00:01:00 -0400 Subject: [PATCH 2/2] Add test for #123 --- tests/test_template.py | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/test_template.py b/tests/test_template.py index 6995697..b7bb7dc 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -2415,3 +2415,55 @@ def test_deduction_sizeof_pack() -> None: ] ) ) + + +def test_template_has_typename() -> None: + content = """ + template + void func(typename V::U arg) {} + """ + data = parse_string(content, cleandoc=True) + + assert data == ParsedData( + namespace=NamespaceScope( + functions=[ + Function( + return_type=Type( + typename=PQName(segments=[FundamentalSpecifier(name="void")]) + ), + name=PQName(segments=[NameSpecifier(name="func")]), + parameters=[ + Parameter( + type=Type( + typename=PQName( + segments=[ + NameSpecifier(name="V"), + NameSpecifier(name="U"), + ], + has_typename=True, + ) + ), + name="arg", + ) + ], + has_body=True, + template=TemplateDecl( + params=[ + TemplateNonTypeParam( + type=Type( + typename=PQName( + segments=[ + NameSpecifier(name="T"), + NameSpecifier(name="Q"), + ], + has_typename=True, + ) + ), + name="value", + ) + ] + ), + ) + ] + ) + )