mescc: Tinycc support: struct.union.

* module/language/c99/compiler.mes (struct-field): Add struct tag to
  struct/union types.
  (field-type, field-size, field-offset, field-field, ast-type->type):
  Ascertain struct tag with type.
* (expr->accu*): Do not add struct tag.
* scaffold/tests/75-struct-union.c: Test it.
* scaffold/tests/71-struct-array.c: Update.
This commit is contained in:
Jan Nieuwenhuizen 2017-07-23 13:41:38 +02:00
parent 1c01a65d8b
commit 1d996c7131
3 changed files with 73 additions and 41 deletions

View file

@ -954,18 +954,18 @@
;; bar.foo.i ;; bar.foo.i
((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0)))) ((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((type0 (ident->type info struct0)) (let* ((type0 (ident->type info struct0))
(type1 (field-type info `("struct" ,type0) field0)) (type1 (field-type info type0 field0))
(offset (+ (field-offset info `("struct" ,type0) field0) (offset (+ (field-offset info type0 field0)
(field-offset info `("struct" ,type1) field1)))) (field-offset info type1 field1))))
(append-text info (append ((ident->accu info) struct0) (append-text info (append ((ident->accu info) struct0)
(wrap-as (i386:accu+value offset)))))) (wrap-as (i386:accu+value offset))))))
;; bar.poo->i ;; bar.poo->i
((i-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0)))) ((i-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((type0 (ident->type info struct0)) (let* ((type0 (ident->type info struct0))
(type1 (field-type info `("struct" ,type0) field0)) (type1 (field-type info type0 field0))
(offset0 (field-offset info `("struct" ,type0) field0)) (offset0 (field-offset info type0 field0))
(offset1 (field-offset info `("struct" ,type1) field1))) (offset1 (field-offset info type1 field1)))
(append-text info (append ((ident->accu info) struct0) (append-text info (append ((ident->accu info) struct0)
(wrap-as (i386:accu+value offset0)) (wrap-as (i386:accu+value offset0))
(wrap-as (i386:mem->accu)) (wrap-as (i386:mem->accu))
@ -974,27 +974,27 @@
;; bar->foo.i ;; bar->foo.i
((d-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0)))) ((d-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((type0 (ident->type info struct0)) (let* ((type0 (ident->type info struct0))
(type1 (field-type info `("struct" ,type0) field0)) (type1 (field-type info type0 field0))
(offset (+ (field-offset info `("struct" ,type0) field0) (offset (+ (field-offset info type0 field0)
(field-offset info `("struct" ,type1) field1)))) (field-offset info type1 field1))))
(append-text info (append ((ident-address->accu info) struct0) (append-text info (append ((ident-address->accu info) struct0)
(wrap-as (i386:accu+value offset)))))) (wrap-as (i386:accu+value offset))))))
;; bar->foo.i ;; bar->foo.i
((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0)))) ((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((type0 (ident->type info struct0)) (let* ((type0 (ident->type info struct0))
(type1 (field-type info `("struct" ,type0) field0)) (type1 (field-type info type0 field0))
(offset (+ (field-offset info `("struct" ,type0) field0) (offset (+ (field-offset info type0 field0)
(field-offset info `("struct" ,type1) field1)))) (field-offset info type1 field1))))
(append-text info (append ((ident->accu info) struct0) (append-text info (append ((ident->accu info) struct0)
(wrap-as (i386:accu+value offset)))))) (wrap-as (i386:accu+value offset))))))
;;(i-sel (ident "i") (i-sel (ident "p") (p-expr (ident "p")))) ;;(i-sel (ident "i") (i-sel (ident "p") (p-expr (ident "p"))))
((i-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0)))) ((i-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0))))
(let* ((type0 (ident->type info struct0)) (let* ((type0 (ident->type info struct0))
(type1 (field-type info `("struct" ,type0) field0)) (type1 (field-type info type0 field0))
(offset0 (field-offset info `("struct" ,type0) field0)) (offset0 (field-offset info type0 field0))
(offset1 (field-offset info `("struct" ,type1) field1))) (offset1 (field-offset info type1 field1)))
(append-text info (append ((ident->accu info) struct0) (append-text info (append ((ident->accu info) struct0)
(wrap-as (i386:accu+value offset0)) (wrap-as (i386:accu+value offset0))
(wrap-as (i386:mem->accu)) (wrap-as (i386:mem->accu))
@ -1003,9 +1003,9 @@
;; (*pp)->bar.foo ;; (*pp)->bar.foo
((d-sel (ident ,field1) (i-sel (ident ,field0) (de-ref (p-expr (ident ,struct0))))) ((d-sel (ident ,field1) (i-sel (ident ,field0) (de-ref (p-expr (ident ,struct0)))))
(let* ((type0 (ident->type info struct0)) (let* ((type0 (ident->type info struct0))
(type1 (field-type info `("struct" ,type0) field0)) (type1 (field-type info type0 field0))
(offset (+ (field-offset info `("struct" ,type0) field0) (offset (+ (field-offset info type0 field0)
(field-offset info `("struct" ,type1) field1)))) (field-offset info type1 field1))))
(append-text info (append ((ident->accu info) struct0) (append-text info (append ((ident->accu info) struct0)
(wrap-as (i386:mem->accu)) (wrap-as (i386:mem->accu))
(wrap-as (i386:accu+value offset)))))) (wrap-as (i386:accu+value offset))))))
@ -1080,9 +1080,9 @@
;; foo[i].bar.baz ;; foo[i].bar.baz
((d-sel (ident ,field1) (d-sel (ident ,field0) (array-ref ,index (p-expr (ident ,array))))) ((d-sel (ident ,field1) (d-sel (ident ,field0) (array-ref ,index (p-expr (ident ,array)))))
(let* ((type0 (ident->type info array)) (let* ((type0 (ident->type info array))
(type1 (field-type info `("struct" ,type0) field0)) (type1 (field-type info type0 field0))
(offset (+ (field-offset info `("struct" ,type0) field0) (offset (+ (field-offset info type0 field0)
(field-offset info `("struct" ,type1) field1))) (field-offset info type1 field1)))
(info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array)))))) (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array))))))
(append-text info (wrap-as (i386:accu+value offset))))) (append-text info (wrap-as (i386:accu+value offset)))))
@ -1159,11 +1159,14 @@
((decl-spec-list (type-qual ,qual) (type-spec (fixed-type ,type))) ((decl-spec-list (type-qual ,qual) (type-spec (fixed-type ,type)))
(ast-type->type info type)) (ast-type->type info type))
((struct-ref (ident (,type))) ((struct-ref (ident (,type)))
(ast-type->type info `("struct" ,type))) (let ((struct (if (pair? type) type `("struct" ,type))))
(ast-type->type info struct)))
((struct-ref (ident ,type)) ((struct-ref (ident ,type))
(ast-type->type info `("struct" ,type))) (let ((struct (if (pair? type) type `("struct" ,type))))
(ast-type->type info struct)))
((union-ref (ident ,type)) ((union-ref (ident ,type))
(ast-type->type info `("struct" ,type))) (let ((struct (if (pair? type) type `("struct" ,type))))
(ast-type->type info struct)))
((void) (ast-type->type info "void")) ((void) (ast-type->type info "void"))
((type-spec (typename ,type)) (ast-type->type info type)) ((type-spec (typename ,type)) (ast-type->type info type))
(_ (let ((type (get-type (.types info) o))) (_ (let ((type (get-type (.types info) o)))
@ -1181,7 +1184,8 @@
(type:size type))) (type:size type)))
(define (field-field info struct field) (define (field-field info struct field)
(let* ((xtype (ast-type->type info struct)) (let* ((struct (if (pair? struct) struct `("struct" ,struct)))
(xtype (ast-type->type info struct))
(fields (type:description xtype))) (fields (type:description xtype)))
(let loop ((fields fields)) (let loop ((fields fields))
(if (null? fields) (error (format #f "no such field: ~a in ~s" field struct)) (if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
@ -1192,7 +1196,8 @@
(else (loop (cdr fields))))))))) (else (loop (cdr fields)))))))))
(define (field-offset info struct field) (define (field-offset info struct field)
(let ((xtype (ast-type->type info struct))) (let* ((struct (if (pair? struct) struct `("struct" ,struct)))
(xtype (ast-type->type info struct)))
(if (eq? (type:type xtype) 'union) 0 (if (eq? (type:type xtype) 'union) 0
(let ((fields (type:description xtype))) (let ((fields (type:description xtype)))
(let loop ((fields fields) (offset 0)) (let loop ((fields fields) (offset 0))
@ -1205,15 +1210,17 @@
(else (loop (cdr fields) (+ offset (field:size f)))))))))))) (else (loop (cdr fields) (+ offset (field:size f))))))))))))
(define (field-size info struct field) (define (field-size info struct field)
(let ((xtype (ast-type->type info struct))) (let* ((struct (if (pair? struct) struct `("struct" ,struct)))
(xtype (ast-type->type info struct)))
(if (eq? (type:type xtype) 'union) 0 (if (eq? (type:type xtype) 'union) 0
(let ((field (field-field info struct field))) (let ((field (field-field info struct field)))
(field:size field))))) (field:size field)))))
(define (field-type info struct field) (define (field-type info struct field)
(let ((xtype (ast-type->type info struct))) (let* ((struct (if (pair? struct) struct `("struct" ,struct)))
(let ((field (field-field info struct field))) (xtype (ast-type->type info struct)))
(field:type field)))) (let ((field (field-field info struct field)))
(field:type field))))
(define (ast->type o) (define (ast->type o)
(pmatch o (pmatch o
@ -1415,23 +1422,27 @@
(list name type (* count size) 0))) (list name type (* count size) 0)))
((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name))))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name)))))
(list name type 4)) (list name `("struct" ,type) 4))
((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name))))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name)))))
(list name type 4)) (list name `("struct" ,type) 4))
((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name))))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name)))))
(list name type 4)) (list name `("struct" ,type) 4))
((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name))))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ptr-declr (pointer) (ident ,name)))))
(list name type 4)) (list name `("struct" ,type) 4))
((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ident ,name)))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident (,type))))) (comp-declr-list (comp-declr (ident ,name))))
((struct-field info) `(comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name)))))) ((struct-field info) `(comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name))))))
((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name)))) ((comp-decl (decl-spec-list (type-spec (struct-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name))))
(let ((size (ast-type->size info `("struct" ,type)))) (let ((size (ast-type->size info `("struct" ,type))))
(list name type size 0))) (list name `("struct" ,type) size 0)))
((comp-decl (decl-spec-list (type-spec (union-ref (ident ,type)))) (comp-declr-list (comp-declr (ident ,name))))
(let ((size (ast-type->size info `("struct" ,type))))
(list name `("struct" ,type) size 0)))
((comp-decl (decl-spec-list (type-spec (union-def (field-list . ,fields))))) ((comp-decl (decl-spec-list (type-spec (union-def (field-list . ,fields)))))
`(union ,@(map (struct-field info) fields))) `(union ,@(map (struct-field info) fields)))

View file

@ -25,7 +25,12 @@ struct foo;
struct foo* krak; struct foo* krak;
#if 0
//FIXME: TODO
typedef struct foo foo_struct; typedef struct foo foo_struct;
#else
typedef struct foo foo;
#endif
struct foo struct foo
{ {
@ -47,8 +52,7 @@ typedef struct baz
int int
test () test ()
{ {
//struct foo f; foo f;
foo_struct f;
f.bar[0] = 0x22; f.bar[0] = 0x22;
f.bar[1] = 0x34; f.bar[1] = 0x34;
printf ("eentje: %d\n", f.bar[0]); printf ("eentje: %d\n", f.bar[0]);

View file

@ -21,7 +21,17 @@
#include "30-test.i" #include "30-test.i"
#include <stdio.h> #include <stdio.h>
union u {
int bar;
int baz;
};
struct foo struct foo
{
union u u;
};
struct anon
{ {
union { union {
int bar; int bar;
@ -29,14 +39,21 @@ struct foo
}; };
}; };
int int
test () test ()
{ {
struct foo f = {2}; struct foo f = {2};
printf ("f.bar=%d\n", f.bar); printf ("f.u.bar=%d\n", f.u.bar);
if (f.bar != 2) return 1; if (f.u.bar != 2) return 1;
printf ("f.baz=%d\n", f.baz); printf ("f.u.baz=%d\n", f.u.baz);
if (f.baz != 2) return 1; if (f.u.baz != 2) return 1;
struct anon a = {2};
printf ("a.bar=%d\n", a.bar);
if (a.bar != 2) return 1;
printf ("a.baz=%d\n", a.baz);
if (a.baz != 2) return 1;
return 0; return 0;
} }