Merge pull request #27 from robotpy/fix-fnptr-w-refs

Handle function pointer parameters where the return value is a reference
This commit is contained in:
Dustin Spicuzza 2021-11-26 00:27:41 -05:00 committed by GitHub
commit 7f6ae6bcbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 141 additions and 1 deletions

View File

@ -1503,7 +1503,6 @@ class CxxParser:
param = self._parse_parameter(None, Parameter)
params.append(param)
tok = self._next_token_must_be(",", ")")
if tok.value == ")":
break
@ -1812,6 +1811,11 @@ class CxxParser:
else:
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
# Applies to variables and return values

View File

@ -3,10 +3,13 @@
from cxxheaderparser.types import (
Array,
AutoSpecifier,
ClassDecl,
Function,
FunctionType,
FundamentalSpecifier,
MoveReference,
NameSpecifier,
Operator,
PQName,
Parameter,
Pointer,
@ -20,6 +23,7 @@ from cxxheaderparser.types import (
Value,
)
from cxxheaderparser.simple import (
ClassScope,
NamespaceScope,
parse_string,
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")
]
)
)
)
],
)
)
)
],
)
]
)
)