Handle function pointer parameters where the return value is a reference

- Fixes #17
This commit is contained in:
Dustin Spicuzza 2021-11-26 00:11:36 -05:00
parent b1808f77ad
commit c7d480e8c3
2 changed files with 141 additions and 1 deletions

View File

@ -1503,7 +1503,6 @@ class CxxParser:
param = self._parse_parameter(None, Parameter) param = self._parse_parameter(None, Parameter)
params.append(param) params.append(param)
tok = self._next_token_must_be(",", ")") tok = self._next_token_must_be(",", ")")
if tok.value == ")": if tok.value == ")":
break break
@ -1812,6 +1811,11 @@ class CxxParser:
else: else:
dtype = MoveReference(dtype) dtype = MoveReference(dtype)
# peek at the next token and see if it's a paren. If so, it might
# be a nasty function pointer
if self.lex.token_peek_if("("):
dtype = self._parse_cv_ptr(dtype, nonptr_fn)
return dtype return dtype
# Applies to variables and return values # Applies to variables and return values

View File

@ -3,10 +3,13 @@
from cxxheaderparser.types import ( from cxxheaderparser.types import (
Array, Array,
AutoSpecifier, AutoSpecifier,
ClassDecl,
Function, Function,
FunctionType, FunctionType,
FundamentalSpecifier, FundamentalSpecifier,
MoveReference,
NameSpecifier, NameSpecifier,
Operator,
PQName, PQName,
Parameter, Parameter,
Pointer, Pointer,
@ -20,6 +23,7 @@ from cxxheaderparser.types import (
Value, Value,
) )
from cxxheaderparser.simple import ( from cxxheaderparser.simple import (
ClassScope,
NamespaceScope, NamespaceScope,
parse_string, parse_string,
ParsedData, ParsedData,
@ -857,3 +861,135 @@ def test_inline_volatile_fn():
] ]
) )
) )
def test_method_w_reference():
content = """
struct StreamBuffer
{
StreamBuffer &operator<<(std::ostream &(*fn)(std::ostream &))
{
return *this;
}
};
"""
data = parse_string(content, cleandoc=True)
assert data == ParsedData(
namespace=NamespaceScope(
classes=[
ClassScope(
class_decl=ClassDecl(
typename=PQName(
segments=[NameSpecifier(name="StreamBuffer")],
classkey="struct",
)
),
methods=[
Operator(
return_type=Reference(
ref_to=Type(
typename=PQName(
segments=[NameSpecifier(name="StreamBuffer")]
)
)
),
name=PQName(segments=[NameSpecifier(name="operator<<")]),
parameters=[
Parameter(
type=Pointer(
ptr_to=FunctionType(
return_type=Reference(
ref_to=Type(
typename=PQName(
segments=[
NameSpecifier(name="std"),
NameSpecifier(
name="ostream"
),
]
)
)
),
parameters=[
Parameter(
type=Reference(
ref_to=Type(
typename=PQName(
segments=[
NameSpecifier(
name="std"
),
NameSpecifier(
name="ostream"
),
]
)
)
)
)
],
)
),
name="fn",
)
],
has_body=True,
access="public",
operator="<<",
)
],
)
]
)
)
def test_fn_w_mvreference():
content = """
void fn1(int && (*)(int));
"""
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="fn1")]),
parameters=[
Parameter(
type=Pointer(
ptr_to=FunctionType(
return_type=MoveReference(
moveref_to=Type(
typename=PQName(
segments=[
FundamentalSpecifier(name="int")
]
)
)
),
parameters=[
Parameter(
type=Type(
typename=PQName(
segments=[
FundamentalSpecifier(name="int")
]
)
)
)
],
)
)
)
],
)
]
)
)