[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[COMMITTED] pkl: support nested integral structs
From: |
Jose E. Marchesi |
Subject: |
[COMMITTED] pkl: support nested integral structs |
Date: |
Thu, 06 Jan 2022 14:09:32 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
This commit expands the support for integral structs to support
nesting them. This is now supported:
type Foo =
struct int<32>
{
struct int<16> { byte a; byte b; } la;
uint<16> le;
};
Mappers, writers, integrators and deintegrators have been adapted
accordingly.
2022-01-06 Jose E. Marchesi <jemarch@gnu.org>
* libpoke/pkl-ast.h: Prototype for pkl_ast_sizeof_integral_type.
* libpoke/pkl-ast.c (pkl_ast_sizeof_integral_type): New function.
* libpoke/pkl-typify.c (pkl_typify1_ps_type_struct): Allow
integral structs nested in other integral structs.
* libpoke/pkl-gen.h (PKL_GEN_CTX_IN_INTEGRATOR): Define.
(PKL_GEN_CTX_IN_DEINTEGRATOR): Likewise.
* libpoke/pkl-gen.c (pkl_gen_pr_decl): Use a dedicated context
when compiling struct type integrators.
(pkl_gen_pr_cast): Likewise.
(pkl_gen_pr_type_struct): Add in_integrator and in_deintegrator
cases.
* libpoke/pkl-gen.pks (struct_field_extractor): Support nested
integral structs.
(struct_field_inserter): Likewise.
(struct_writer): Likewise.
(struct_integrator): Likewise.
(deint_extract_field_value): Likewise.
(struct_deintegrator): Likewise.
* testsuite/poke.pkl/int-struct-type-diag-9.pk: Rewrite test.
* testsuite/poke.pkl/int-struct-type-diag-15.pk: New test.
* testsuite/poke.pkl/int-struct-3.pk: Likewise.
* testsuite/poke.pkl/int-struct-4.pk: Likewise.
* testsuite/poke.map/maps-int-structs-29.pk: Likewise.
* testsuite/poke.pkl/scons-int-struct-5.pk: Likewise.
* testsuite/poke.pkl/deint-struct-10.pk: Likewise.
* testsuite/poke.pkl/deint-struct-11.pk: Likewise.
* testsuite/poke.map/ass-map-24.pk: Likewise.
* testsuite/poke.map/asss-map-25.pk: Likewise.
* testsuite/Makefile.am (EXTRA_DIST): Add new tests.
---
ChangeLog | 32 ++++++++++
libpoke/pkl-ast.c | 23 +++++++
libpoke/pkl-ast.h | 2 +
libpoke/pkl-gen.c | 92 +++++++++++----------------
libpoke/pkl-gen.h | 2 +
libpoke/pkl-gen.pks | 56 ++++++++++++++--
libpoke/pkl-typify.c | 16 ++---
testsuite/Makefile.am | 9 +++
testsuite/poke.map/ass-map-24.pk | 14 ++++
testsuite/poke.map/ass-map-25.pk | 12 ++++
testsuite/poke.map/maps-int-structs-29.pk | 24 +++++++
testsuite/poke.pkl/deint-struct-10.pk | 7 ++
testsuite/poke.pkl/deint-struct-11.pk | 7 ++
testsuite/poke.pkl/int-struct-3.pk | 4 ++
testsuite/poke.pkl/int-struct-4.pk | 9 +++
testsuite/poke.pkl/int-struct-type-diag-15.pk | 13 ++++
testsuite/poke.pkl/int-struct-type-diag-9.pk | 13 ++--
testsuite/poke.pkl/scons-int-struct-5.pk | 11 ++++
18 files changed, 268 insertions(+), 78 deletions(-)
create mode 100644 testsuite/poke.map/ass-map-24.pk
create mode 100644 testsuite/poke.map/ass-map-25.pk
create mode 100644 testsuite/poke.map/maps-int-structs-29.pk
create mode 100644 testsuite/poke.pkl/deint-struct-10.pk
create mode 100644 testsuite/poke.pkl/deint-struct-11.pk
create mode 100644 testsuite/poke.pkl/int-struct-3.pk
create mode 100644 testsuite/poke.pkl/int-struct-4.pk
create mode 100644 testsuite/poke.pkl/int-struct-type-diag-15.pk
create mode 100644 testsuite/poke.pkl/scons-int-struct-5.pk
diff --git a/ChangeLog b/ChangeLog
index c54519cb..f4f1db1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2022-01-06 Jose E. Marchesi <jemarch@gnu.org>
+
+ * libpoke/pkl-ast.h: Prototype for pkl_ast_sizeof_integral_type.
+ * libpoke/pkl-ast.c (pkl_ast_sizeof_integral_type): New function.
+ * libpoke/pkl-typify.c (pkl_typify1_ps_type_struct): Allow
+ integral structs nested in other integral structs.
+ * libpoke/pkl-gen.h (PKL_GEN_CTX_IN_INTEGRATOR): Define.
+ (PKL_GEN_CTX_IN_DEINTEGRATOR): Likewise.
+ * libpoke/pkl-gen.c (pkl_gen_pr_decl): Use a dedicated context
+ when compiling struct type integrators.
+ (pkl_gen_pr_cast): Likewise.
+ (pkl_gen_pr_type_struct): Add in_integrator and in_deintegrator
+ cases.
+ * libpoke/pkl-gen.pks (struct_field_extractor): Support nested
+ integral structs.
+ (struct_field_inserter): Likewise.
+ (struct_writer): Likewise.
+ (struct_integrator): Likewise.
+ (deint_extract_field_value): Likewise.
+ (struct_deintegrator): Likewise.
+ * testsuite/poke.pkl/int-struct-type-diag-9.pk: Rewrite test.
+ * testsuite/poke.pkl/int-struct-type-diag-15.pk: New test.
+ * testsuite/poke.pkl/int-struct-3.pk: Likewise.
+ * testsuite/poke.pkl/int-struct-4.pk: Likewise.
+ * testsuite/poke.map/maps-int-structs-29.pk: Likewise.
+ * testsuite/poke.pkl/scons-int-struct-5.pk: Likewise.
+ * testsuite/poke.pkl/deint-struct-10.pk: Likewise.
+ * testsuite/poke.pkl/deint-struct-11.pk: Likewise.
+ * testsuite/poke.map/ass-map-24.pk: Likewise.
+ * testsuite/poke.map/asss-map-25.pk: Likewise.
+ * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+
2022-01-05 Jose E. Marchesi <jemarch@gnu.org>
* testsuite/Makefile.am (EXTRA_DIST): Add missing test.
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index 7212b06a..86944065 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -1060,6 +1060,29 @@ pkl_ast_sizeof_type (pkl_ast ast, pkl_ast_node type)
return res;
}
+/* Return the size (in bits) of values of the given type, which must
+ be an integral, offset or integral struct type. */
+
+size_t
+pkl_ast_sizeof_integral_type (pkl_ast_node type)
+{
+ if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_INTEGRAL)
+ return PKL_AST_TYPE_I_SIZE (type);
+ else if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_OFFSET)
+ {
+ pkl_ast_node base_type = PKL_AST_TYPE_O_BASE_TYPE (type);
+ return PKL_AST_TYPE_I_SIZE (base_type);
+ }
+ else if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_STRUCT
+ && PKL_AST_TYPE_S_ITYPE (type) != NULL)
+ {
+ pkl_ast_node itype = PKL_AST_TYPE_S_ITYPE (type);
+ return PKL_AST_TYPE_I_SIZE (itype);
+ }
+ else
+ assert (0);
+}
+
/* Return 1 if the given TYPE can be mapped in IO. 0 otherwise. */
int
diff --git a/libpoke/pkl-ast.h b/libpoke/pkl-ast.h
index 96a4cb8c..31066b9e 100644
--- a/libpoke/pkl-ast.h
+++ b/libpoke/pkl-ast.h
@@ -1023,6 +1023,8 @@ int pkl_ast_type_promoteable_p (pkl_ast_node ft,
pkl_ast_node tt,
pkl_ast_node pkl_ast_sizeof_type (pkl_ast ast, pkl_ast_node type);
+size_t pkl_ast_sizeof_integral_type (pkl_ast_node type);
+
int pkl_ast_type_is_complete (pkl_ast_node type);
void pkl_ast_array_type_remove_bounders (pkl_ast_node type);
diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
index 1a3fb31c..846155ad 100644
--- a/libpoke/pkl-gen.c
+++ b/libpoke/pkl-gen.c
@@ -271,11 +271,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
{
pvm_val integrator_closure;
- /* Yes, the in_writer context is also used for
- integrators, since integrators do not call
- writers nor the other way around. This eases
- sharing of code in the pks. */
- PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
+ PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
type_struct);
PKL_GEN_POP_CONTEXT;
@@ -291,11 +287,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
{
pvm_val deintegrator_closure;
- /* Yes, the in_writer context is also used for
- deintegrators, since deintegrators do not call
- writers nor the other way around. This eases
- sharing of code in the pks. */
- PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
+ PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
type_struct);
PKL_GEN_POP_CONTEXT;
@@ -2234,32 +2226,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_cast)
else if (PKL_AST_TYPE_CODE (to_type) == PKL_TYPE_STRUCT
&& PKL_AST_TYPE_CODE (from_type) == PKL_TYPE_INTEGRAL)
{
- pkl_ast_node itype = PKL_AST_TYPE_S_ITYPE (to_type);
-
- /* This is guaranteed as per typify. */
- assert (itype);
-
- /* Make sure the struct type has a deintegrator. */
- if (PKL_AST_TYPE_S_DEINTEGRATOR (to_type) == PVM_NULL)
- {
- pvm_val deintegrator_closure;
-
- /* See note about in_writer in pkl_gen_pr_decl. */
- PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
- RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
- to_type); /* CLS */
-
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, deintegrator_closure); /*
CLS */
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC); /*
CLS */
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP); /*
_ */
- PKL_GEN_POP_CONTEXT;
-
- PKL_AST_TYPE_S_DEINTEGRATOR (to_type) = deintegrator_closure;
- }
-
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
- PKL_AST_TYPE_S_DEINTEGRATOR (to_type));
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
+ PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
+ PKL_PASS_SUBPASS (to_type);
+ PKL_GEN_POP_CONTEXT;
}
else if (PKL_AST_TYPE_CODE (to_type) == PKL_TYPE_INTEGRAL
&& PKL_AST_TYPE_CODE (from_type) == PKL_TYPE_STRUCT)
@@ -2269,27 +2238,10 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_cast)
/* This is guaranteed as per typify. */
assert (itype);
- /* Make sure the struct type has an integrator. */
- if (PKL_AST_TYPE_S_INTEGRATOR (from_type) == PVM_NULL)
- {
- pvm_val integrator_closure;
-
- /* See note about in_writer in pkl_gen_pr_decl. */
- PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
- RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
- from_type); /* CLS */
-
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, integrator_closure); /*
CLS */
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC); /*
CLS */
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP); /* _
*/
- PKL_GEN_POP_CONTEXT;
-
- PKL_AST_TYPE_S_INTEGRATOR (from_type) = integrator_closure;
- }
+ PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
+ PKL_PASS_SUBPASS (from_type);
+ PKL_GEN_POP_CONTEXT;
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
- PKL_AST_TYPE_S_INTEGRATOR (from_type));
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
pkl_asm_insn (pasm, PKL_INSN_NTON, itype, to_type);
pkl_asm_insn (pasm, PKL_INSN_NIP);
}
@@ -3582,6 +3534,34 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL); /* _ */
PKL_PASS_BREAK;
}
+ else if (PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_INTEGRATOR))
+ {
+ pkl_ast_node type_struct = PKL_PASS_NODE;
+ pvm_val integrator_closure = PKL_AST_TYPE_S_INTEGRATOR (type_struct);
+
+ if (integrator_closure == PVM_NULL)
+ RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure, type_struct);
+ pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, integrator_closure);
+ if (!PKL_AST_TYPE_NAME (type_struct))
+ pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
+
+ pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
+ PKL_PASS_BREAK;
+ }
+ else if (PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_DEINTEGRATOR))
+ {
+ pkl_ast_node type_struct = PKL_PASS_NODE;
+ pvm_val deintegrator_closure = PKL_AST_TYPE_S_DEINTEGRATOR (type_struct);
+
+ if (deintegrator_closure == PVM_NULL)
+ RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure, type_struct);
+ pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, deintegrator_closure);
+ if (!PKL_AST_TYPE_NAME (type_struct))
+ pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
+
+ pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
+ PKL_PASS_BREAK;
+ }
else if (PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_TYPE))
{
/* Do nothing. See PS hook. */
diff --git a/libpoke/pkl-gen.h b/libpoke/pkl-gen.h
index a2315dec..1853b868 100644
--- a/libpoke/pkl-gen.h
+++ b/libpoke/pkl-gen.h
@@ -112,6 +112,8 @@ typedef struct pkl_gen_payload *pkl_gen_payload;
#define PKL_GEN_CTX_IN_FUNCALL 0x200
#define PKL_GEN_CTX_IN_TYPE 0x400
#define PKL_GEN_CTX_IN_FORMATER 0x800
+#define PKL_GEN_CTX_IN_INTEGRATOR 0x1000
+#define PKL_GEN_CTX_IN_DEINTEGRATOR 0x2000
extern struct pkl_phase pkl_phase_gen;
diff --git a/libpoke/pkl-gen.pks b/libpoke/pkl-gen.pks
index e1c198b3..f47dd430 100644
--- a/libpoke/pkl-gen.pks
+++ b/libpoke/pkl-gen.pks
@@ -671,7 +671,8 @@
nip ; STRICT BOFF IVAL SCOUNT(U)
;; Using the calculated bit-count, extract the value of the
;; field from the struct ival. The resulting value is converted
- ;; to the type of the field. (base type if the field is offset.)
+ ;; to the type of the field. (base type if the field is offset,
+ ;; itype if the field is an integral struct.)
sr @struct_itype
nip2 ; STRICT BOFF VAL
.c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
@@ -679,13 +680,19 @@
.let @base_type = PKL_AST_TYPE_O_BASE_TYPE (@field_type)
nton @struct_itype, @base_type
.c }
+ .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+ .c {
+ .let @field_itype = PKL_AST_TYPE_S_ITYPE (@field_type)
+ nton @struct_itype, @field_itype
+ .c }
.c else
.c {
nton @struct_itype, @field_type
.c }
nip ; STRICT BOFF VALC
;; At this point the value of the field is in the
- ;; stack. If the field is an offset, construct it.
+ ;; stack. The field may be an integral or an offset
+ ;; or an integral struct.
.c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
.c {
.let @offset_unit = PKL_AST_TYPE_O_UNIT (@field_type)
@@ -693,6 +700,12 @@
push #unit ; STRICT BOFF MVALC UNIT
mko ; STRICT BOFF VALC
.c }
+ .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+ .c {
+ .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
+ .c PKL_PASS_SUBPASS (@field_type);
+ .c PKL_GEN_POP_CONTEXT;
+ .c }
dup ; STRICT BOFF VALC VALC
regvar $val ; STRICT BOFF VALC
.c vars_registered++;
@@ -879,6 +892,8 @@
.c size_t field_type_size
.c = (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET
.c ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_O_BASE_TYPE (@field_type))
+ .c : PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT
+ .c ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_S_ITYPE (@field_type))
.c : PKL_AST_TYPE_I_SIZE (@field_type));
.let #fieldw = pvm_make_ulong (field_type_size, 64);
;; Note that at this point the field is assured to be
@@ -1540,6 +1555,16 @@
nip ; SCT I (IVALW-REOFF-FIELDW) EVAL [IVAL]
nton @base_type, @struct_itype
.c }
+ .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+ .c {
+ ;; EVAL is an integral struct. Integrate it to get its integral
+ ;; value.
+ .let @field_itype = PKL_AST_TYPE_S_ITYPE (@field_type)
+ .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
+ .c PKL_PASS_SUBPASS (@field_type);
+ .c PKL_GEN_POP_CONTEXT;
+ nton @field_itype, @struct_itype
+ .c }
.c else
.c {
nton @field_type, @struct_itype
@@ -1651,6 +1676,8 @@
.c size_t field_type_size
.c = (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET
.c ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_O_BASE_TYPE (@field_type))
+ .c : PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT
+ .c ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_S_ITYPE (@field_type))
.c : PKL_AST_TYPE_I_SIZE (@field_type));
.let #fieldw = pvm_make_ulong (field_type_size, 64);
pushvar $ivalue ; SCT I IVAL
@@ -1804,6 +1831,8 @@
.c size_t field_type_size
.c = (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET
.c ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_O_BASE_TYPE (@field_type))
+ .c : PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT
+ .c ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_S_ITYPE (@field_type))
.c : PKL_AST_TYPE_I_SIZE (@field_type));
.let #fieldw = pvm_make_ulong (field_type_size, 64);
pushvar $ivalue ; SCT I IVAL
@@ -1830,8 +1859,11 @@
.macro deint_extract_field_value @uint64_type @itype @field_type
#bit_offset
.let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
- .let @field_int_type = PKL_AST_TYPE_CODE (@field_type) ==
PKL_TYPE_OFFSET ? \
- PKL_AST_TYPE_O_BASE_TYPE (@field_type) :
@field_type
+ .let @field_int_type = (PKL_AST_TYPE_CODE (@field_type) ==
PKL_TYPE_OFFSET \
+ ? PKL_AST_TYPE_O_BASE_TYPE (@field_type) \
+ : PKL_AST_TYPE_CODE (@field_type) ==
PKL_TYPE_STRUCT \
+ ? PKL_AST_TYPE_S_ITYPE (@field_type) \
+ : @field_type)
.c size_t field_type_size = PKL_AST_TYPE_I_SIZE (@field_int_type);
.c size_t itype_bits = PKL_AST_TYPE_I_SIZE (@itype);
;; Field extraction:
@@ -1845,7 +1877,8 @@
nip2
;; Convert the extracted value to the type of the field. If
;; the field is an offset, set an offset with the extracted
- ;; value as magnitude and same unit.
+ ;; value as magnitude and same unit. If the field is an
+ ;; integral struct, call its deintegrator.
nton @uint64_type, @field_int_type
nip
.c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
@@ -1855,6 +1888,12 @@
push #unit
mko
.c }
+ .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+ .c {
+ .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
+ .c PKL_PASS_SUBPASS (@field_type);
+ .c PKL_GEN_POP_CONTEXT;
+ .c }
.end
;;; RAS_FUNCTION_STRUCT_DEINTEGRATOR @type_struct
@@ -1896,8 +1935,11 @@
.c continue;
.let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
.c size_t field_type_size
- .c = PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_CODE (@field_type) ==
PKL_TYPE_OFFSET
- .c ? PKL_AST_TYPE_O_BASE_TYPE (@field_type) : @field_type);
+ .c = (PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_CODE (@field_type) ==
PKL_TYPE_OFFSET
+ .c ? PKL_AST_TYPE_O_BASE_TYPE (@field_type)
+ .c : PKL_AST_TYPE_CODE (@field_type) ==
PKL_TYPE_STRUCT
+ .c ? PKL_AST_TYPE_S_ITYPE (@field_type)
+ .c : @field_type));
;; Anonymous fields are not handled in this loop, but we have
;; to advance the offset nevertheless.
.let @type_field_name = PKL_AST_STRUCT_TYPE_FIELD_NAME (@field)
diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
index ad8da7fc..25fbff8c 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -1771,8 +1771,8 @@ PKL_PHASE_END_HANDLER
/* The type associated with an integral struct shall be integral.
The fields in an integral struct type shall be all of integral or
- offset types (_not_ including other integral structs) and the total
- int size shall match the sum of the sizes of all the fields.
+ offset types (including other integral structs) and the total int
+ size shall match the sum of the sizes of all the fields.
The total size declared in the integral struct should exactly match
the size of all the contained fields.
@@ -1820,7 +1820,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
= PKL_AST_STRUCT_TYPE_FIELD_TYPE (field);
if (PKL_AST_TYPE_CODE (ftype) != PKL_TYPE_INTEGRAL
- && PKL_AST_TYPE_CODE (ftype) != PKL_TYPE_OFFSET)
+ && PKL_AST_TYPE_CODE (ftype) != PKL_TYPE_OFFSET
+ && !(PKL_AST_TYPE_CODE (ftype) == PKL_TYPE_STRUCT
+ && PKL_AST_TYPE_S_ITYPE (ftype) != NULL))
{
PKL_ERROR (PKL_AST_LOC (field),
"invalid field in integral struct");
@@ -1844,13 +1846,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
PKL_PASS_ERROR;
}
- if (PKL_AST_TYPE_CODE (ftype) == PKL_TYPE_INTEGRAL)
- fields_int_size += PKL_AST_TYPE_I_SIZE (ftype);
- else
- {
- pkl_ast_node base_type = PKL_AST_TYPE_O_BASE_TYPE (ftype);
- fields_int_size += PKL_AST_TYPE_I_SIZE (base_type);
- }
+ fields_int_size += pkl_ast_sizeof_integral_type (ftype);
}
}
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 31cc7ba5..754c91f5 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -135,6 +135,8 @@ EXTRA_DIST = \
poke.map/ass-map-21.pk \
poke.map/ass-map-22.pk \
poke.map/ass-map-23.pk \
+ poke.map/ass-map-24.pk \
+ poke.map/ass-map-25.pk \
poke.map/ass-map-struct-int-1.pk \
poke.map/func-map-1.pk \
poke.map/func-map-2.pk \
@@ -264,6 +266,7 @@ EXTRA_DIST = \
poke.map/maps-int-structs-26.pk \
poke.map/maps-int-structs-27.pk \
poke.map/maps-int-structs-28.pk \
+ poke.map/maps-int-structs-29.pk \
poke.map/maps-ios-1.pk \
poke.map/maps-ios-2.pk \
poke.map/maps-ios-3.pk \
@@ -930,6 +933,8 @@ EXTRA_DIST = \
poke.pkl/defvar-5.pk \
poke.pkl/defvar-6.pk \
poke.pkl/deint-struct-1.pk \
+ poke.pkl/deint-struct-10.pk \
+ poke.pkl/deint-struct-11.pk \
poke.pkl/deint-struct-2.pk \
poke.pkl/deint-struct-3.pk \
poke.pkl/deint-struct-4.pk \
@@ -1203,6 +1208,8 @@ EXTRA_DIST = \
poke.pkl/in-diag-3.pk \
poke.pkl/int-struct-1.pk \
poke.pkl/int-struct-2.pk \
+ poke.pkl/int-struct-3.pk \
+ poke.pkl/int-struct-4.pk \
poke.pkl/int-struct-type-diag-1.pk \
poke.pkl/int-struct-type-diag-2.pk \
poke.pkl/int-struct-type-diag-3.pk \
@@ -1217,6 +1224,7 @@ EXTRA_DIST = \
poke.pkl/int-struct-type-diag-12.pk \
poke.pkl/int-struct-type-diag-13.pk \
poke.pkl/int-struct-type-diag-14.pk \
+ poke.pkl/int-struct-type-diag-15.pk \
poke.pkl/int-type-diag-1.pk \
poke.pkl/int-type-diag-2.pk \
poke.pkl/int-type.pk \
@@ -1741,6 +1749,7 @@ EXTRA_DIST = \
poke.pkl/scons-int-struct-2.pk \
poke.pkl/scons-int-struct-3.pk \
poke.pkl/scons-int-struct-4.pk \
+ poke.pkl/scons-int-struct-5.pk \
poke.pkl/scons-label-1.pk \
poke.pkl/scons-offset-1.pk \
poke.pkl/scons-offset-2.pk \
diff --git a/testsuite/poke.map/ass-map-24.pk b/testsuite/poke.map/ass-map-24.pk
new file mode 100644
index 00000000..db0e6f64
--- /dev/null
+++ b/testsuite/poke.map/ass-map-24.pk
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00} } */
+
+type Bar = struct int<24> { byte b; byte c; byte d; };
+
+type Foo = struct uint<32> { byte a; Bar e; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command {.set endian little} } */
+/* { dg-command {Foo @ 1#B = Foo { a = 0xde, e = Bar { b = 0xad, c = 0xbe, d =
0xef }}} } */
+/* { dg-command { int @ 1#B } } */
+/* { dg-output "0xdeadbeef" } */
+/* { dg-command { byte[4] @ 1#B } } */
+/* { dg-output"\n\\\[0xefUB,0xbeUB,0xadUB,0xdeUB\\\]" } */
diff --git a/testsuite/poke.map/ass-map-25.pk b/testsuite/poke.map/ass-map-25.pk
new file mode 100644
index 00000000..d7ddc182
--- /dev/null
+++ b/testsuite/poke.map/ass-map-25.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00} } */
+
+type Bar = struct int<32> { uint<16> a; byte b; byte c; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command {.set endian little} } */
+/* { dg-command {Bar @ 1#B = Bar { a = 0xdead, b = 0xbe, c = 0xef }} } */
+/* { dg-command { int @ 1#B } } */
+/* { dg-output "0xdeadbeef" } */
+/* { dg-command { byte[4] @ 1#B } } */
+/* { dg-output"\n\\\[0xefUB,0xbeUB,0xadUB,0xdeUB\\\]" } */
diff --git a/testsuite/poke.map/maps-int-structs-29.pk
b/testsuite/poke.map/maps-int-structs-29.pk
new file mode 100644
index 00000000..0317fa2d
--- /dev/null
+++ b/testsuite/poke.map/maps-int-structs-29.pk
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0
0xc0} } */
+
+type Foo =
+ struct int<32>
+ {
+ struct int<16>
+ {
+ byte a;
+ byte b;
+ } la;
+
+ uint<16> le;
+ };
+
+/* { dg-command { .set obase 16 } } */
+/* { dg-command { .set endian little } } */
+/* { dg-command { var f = Foo @ 0#B } } */
+/* { dg-command { f.la.a } } */
+/* { dg-output "0x40UB" } */
+/* { dg-command { f.la.b } } */
+/* { dg-output "\n0x30UB" } */
+/* { dg-command { f.le } } */
+/* { dg-output "\n0x2010UH" } */
diff --git a/testsuite/poke.pkl/deint-struct-10.pk
b/testsuite/poke.pkl/deint-struct-10.pk
new file mode 100644
index 00000000..2d253ecc
--- /dev/null
+++ b/testsuite/poke.pkl/deint-struct-10.pk
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+
+type Foo = struct int<32> { struct int<16> { byte a; byte b; } la; uint<16>
le; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command { 0xdeadbeef as Foo } } */
+/* { dg-output "Foo \{la=struct \{a=0xdeUB,b=0xadUB\},le=0xbeefUH\}" } */
diff --git a/testsuite/poke.pkl/deint-struct-11.pk
b/testsuite/poke.pkl/deint-struct-11.pk
new file mode 100644
index 00000000..49d8bd00
--- /dev/null
+++ b/testsuite/poke.pkl/deint-struct-11.pk
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+
+type Foo = struct int<32> { struct int<16> { byte a; struct uint<8> { byte x;
} b; } la; uint<16> le; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command { 0xdeadbeef as Foo } } */
+/* { dg-output "Foo \{la=struct \{a=0xdeUB,b=struct
\{x=0xadUB\}\},le=0xbeefUH\}" } */
diff --git a/testsuite/poke.pkl/int-struct-3.pk
b/testsuite/poke.pkl/int-struct-3.pk
new file mode 100644
index 00000000..8c68fb10
--- /dev/null
+++ b/testsuite/poke.pkl/int-struct-3.pk
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+
+type Bar = struct int<16> { int<8> a; int<8> b; };
+type Foo = struct int<32> { Bar la; int<16> c; };
diff --git a/testsuite/poke.pkl/int-struct-4.pk
b/testsuite/poke.pkl/int-struct-4.pk
new file mode 100644
index 00000000..0de71b17
--- /dev/null
+++ b/testsuite/poke.pkl/int-struct-4.pk
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+
+type Foo =
+ struct int<32>
+ {
+ struct int<16> { int<8> a; int<8> b; } la;
+ int<16> c;
+ };
diff --git a/testsuite/poke.pkl/int-struct-type-diag-15.pk
b/testsuite/poke.pkl/int-struct-type-diag-15.pk
new file mode 100644
index 00000000..4c61bb4c
--- /dev/null
+++ b/testsuite/poke.pkl/int-struct-type-diag-15.pk
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+type Foo =
+ struct int<32>
+ {
+ struct int<10> /* { dg-error "invalid total size" } */
+ {
+ byte a;
+ byte b;
+ } la;
+
+ uint<16> le;
+ };
diff --git a/testsuite/poke.pkl/int-struct-type-diag-9.pk
b/testsuite/poke.pkl/int-struct-type-diag-9.pk
index 4108f6d7..f6075c17 100644
--- a/testsuite/poke.pkl/int-struct-type-diag-9.pk
+++ b/testsuite/poke.pkl/int-struct-type-diag-9.pk
@@ -1,10 +1,13 @@
/* { dg-do compile } */
type Foo =
- struct uint<32>
- { struct int<15> /* { dg-error "invalid field" } */
+ struct int<33> /* { dg-error "invalid total size" } */
+ {
+ struct int<16>
{
- int<15> c;
- } a;
- int<17> b;
+ byte a;
+ byte b;
+ } la;
+
+ uint<16> le;
};
diff --git a/testsuite/poke.pkl/scons-int-struct-5.pk
b/testsuite/poke.pkl/scons-int-struct-5.pk
new file mode 100644
index 00000000..eb5923b8
--- /dev/null
+++ b/testsuite/poke.pkl/scons-int-struct-5.pk
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+
+type Foo = struct int<32> { struct int<16> { byte a; byte b; } la; uint<16>
le; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command { var f = Foo { le = 0xffff } } } */
+/* { dg-command { f.la.b = 0x11 } } */
+/* { dg-command { +f } } */
+/* { dg-output "0x11ffff" } */
+/* { dg-command { f - 1 } } */
+/* { dg-output "\n0x11fffe" } */
--
2.11.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [COMMITTED] pkl: support nested integral structs,
Jose E. Marchesi <=