Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions cxxheaderparser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1407,10 +1407,14 @@ def _discard_ctor_initializer(self) -> None:
# Variable parsing
#

def _parse_bitfield(self) -> int:
# is a integral constant expression... for now, just do integers
tok = self._next_token_must_be("INT_CONST_DEC")
return int(tok.value)
def _parse_bitfield(self) -> typing.Union[int, Value]:
# Convert to integer for backwards compat
tok = self.lex.token_if("INT_CONST_DEC")
if tok is not None:
return int(tok.value)

# But also support weird things too
return self._create_value(self._consume_value_until([], ";"))

def _parse_field(
self,
Expand Down
2 changes: 1 addition & 1 deletion cxxheaderparser/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ class Field:
name: typing.Optional[str] = None

value: typing.Optional[Value] = None
bits: typing.Optional[int] = None
bits: typing.Union[None, int, Value] = None

constexpr: bool = False
mutable: bool = False
Expand Down
159 changes: 0 additions & 159 deletions tests/test_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
Enumerator,
Field,
ForwardDecl,
Function,
FundamentalSpecifier,
Method,
MoveReference,
Expand Down Expand Up @@ -1416,164 +1415,6 @@ def test_class_volatile_move_deleted_fn() -> None:
)


def test_class_bitfield_1() -> None:
content = """
struct S {
// will usually occupy 2 bytes:
// 3 bits: value of b1
// 2 bits: unused
// 6 bits: value of b2
// 2 bits: value of b3
// 3 bits: unused
unsigned char b1 : 3, : 2, b2 : 6, b3 : 2;
};
"""
data = parse_string(content, cleandoc=True)

assert data == ParsedData(
namespace=NamespaceScope(
classes=[
ClassScope(
class_decl=ClassDecl(
typename=PQName(
segments=[NameSpecifier(name="S")], classkey="struct"
)
),
fields=[
Field(
name="b1",
type=Type(
typename=PQName(
segments=[
FundamentalSpecifier(name="unsigned char")
]
)
),
access="public",
bits=3,
),
Field(
type=Type(
typename=PQName(
segments=[
FundamentalSpecifier(name="unsigned char")
]
)
),
access="public",
bits=2,
),
Field(
name="b2",
type=Type(
typename=PQName(
segments=[
FundamentalSpecifier(name="unsigned char")
]
)
),
access="public",
bits=6,
),
Field(
name="b3",
type=Type(
typename=PQName(
segments=[
FundamentalSpecifier(name="unsigned char")
]
)
),
access="public",
bits=2,
),
],
)
]
)
)


def test_class_bitfield_2() -> None:
content = """
struct HAL_ControlWord {
int x : 1;
int y : 1;
};
typedef struct HAL_ControlWord HAL_ControlWord;
int HAL_GetControlWord(HAL_ControlWord *controlWord);
"""
data = parse_string(content, cleandoc=True)

assert data == ParsedData(
namespace=NamespaceScope(
classes=[
ClassScope(
class_decl=ClassDecl(
typename=PQName(
segments=[NameSpecifier(name="HAL_ControlWord")],
classkey="struct",
)
),
fields=[
Field(
name="x",
type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="int")]
)
),
access="public",
bits=1,
),
Field(
name="y",
type=Type(
typename=PQName(
segments=[FundamentalSpecifier(name="int")]
)
),
access="public",
bits=1,
),
],
)
],
functions=[
Function(
return_type=Type(
typename=PQName(segments=[FundamentalSpecifier(name="int")])
),
name=PQName(segments=[NameSpecifier(name="HAL_GetControlWord")]),
parameters=[
Parameter(
type=Pointer(
ptr_to=Type(
typename=PQName(
segments=[NameSpecifier(name="HAL_ControlWord")]
)
)
),
name="controlWord",
)
],
)
],
typedefs=[
Typedef(
type=Type(
typename=PQName(
segments=[NameSpecifier(name="HAL_ControlWord")],
classkey="struct",
)
),
name="HAL_ControlWord",
)
],
)
)


def test_class_anon_struct_as_globalvar() -> None:
content = """
struct {
Expand Down
Loading
Loading