mescc: Tinycc support: struct.union.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 23 Jul 2017 11:41:38 +0000 (13:41 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Wed, 26 Jul 2017 09:36:08 +0000 (11:36 +0200)
* 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.

module/language/c99/compiler.mes
scaffold/tests/71-struct-array.c
scaffold/tests/75-struct-union.c

index e8d666dc11ec9cc89dcf8661812e0d9c47fcf6b3..7ff333ed547235b552a7542007dc2bc5e622b0f6 100644 (file)
       ;; bar.foo.i
       ((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0))))
        (let* ((type0 (ident->type info struct0))
-              (type1 (field-type info `("struct" ,type0) field0))
-              (offset (+ (field-offset info `("struct" ,type0) field0)
-                         (field-offset info `("struct" ,type1) field1))))
+              (type1 (field-type info type0 field0))
+              (offset (+ (field-offset info type0 field0)
+                         (field-offset info type1 field1))))
          (append-text info (append ((ident->accu info) struct0)
                                    (wrap-as (i386:accu+value offset))))))
 
       ;; bar.poo->i
       ((i-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0))))
        (let* ((type0 (ident->type info struct0))
-              (type1 (field-type info `("struct" ,type0) field0))
-              (offset0 (field-offset info `("struct" ,type0) field0))
-              (offset1 (field-offset info `("struct" ,type1) field1)))
+              (type1 (field-type info type0 field0))
+              (offset0 (field-offset info type0 field0))
+              (offset1 (field-offset info type1 field1)))
          (append-text info (append ((ident->accu info) struct0)
                                    (wrap-as (i386:accu+value offset0))
                                    (wrap-as (i386:mem->accu))
       ;; bar->foo.i
       ((d-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0))))
        (let* ((type0 (ident->type info struct0))
-              (type1 (field-type info `("struct" ,type0) field0))
-              (offset (+ (field-offset info `("struct" ,type0) field0)
-                         (field-offset info `("struct" ,type1) field1))))
+              (type1 (field-type info type0 field0))
+              (offset (+ (field-offset info type0 field0)
+                         (field-offset info type1 field1))))
          (append-text info (append ((ident-address->accu info) struct0)
                                    (wrap-as (i386:accu+value offset))))))
 
       ;; bar->foo.i
       ((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0))))
        (let* ((type0 (ident->type info struct0))
-              (type1 (field-type info `("struct" ,type0) field0))
-              (offset (+ (field-offset info `("struct" ,type0) field0)
-                         (field-offset info `("struct" ,type1) field1))))
+              (type1 (field-type info type0 field0))
+              (offset (+ (field-offset info type0 field0)
+                         (field-offset info type1 field1))))
          (append-text info (append ((ident->accu info) struct0)
                                    (wrap-as (i386:accu+value offset))))))
 
       ;;(i-sel (ident "i") (i-sel (ident "p") (p-expr (ident "p"))))
       ((i-sel (ident ,field1) (i-sel (ident ,field0) (p-expr (ident ,struct0))))
        (let* ((type0 (ident->type info struct0))
-              (type1 (field-type info `("struct" ,type0) field0))
-              (offset0 (field-offset info `("struct" ,type0) field0))
-              (offset1 (field-offset info `("struct" ,type1) field1)))
+              (type1 (field-type info type0 field0))
+              (offset0 (field-offset info type0 field0))
+              (offset1 (field-offset info type1 field1)))
          (append-text info (append ((ident->accu info) struct0)
                                    (wrap-as (i386:accu+value offset0))
                                    (wrap-as (i386:mem->accu))
       ;; (*pp)->bar.foo
       ((d-sel (ident ,field1) (i-sel (ident ,field0) (de-ref (p-expr (ident ,struct0)))))
        (let* ((type0 (ident->type info struct0))
-              (type1 (field-type info `("struct" ,type0) field0))
-              (offset (+ (field-offset info `("struct" ,type0) field0)
-                         (field-offset info `("struct" ,type1) field1))))
+              (type1 (field-type info type0 field0))
+              (offset (+ (field-offset info type0 field0)
+                         (field-offset info type1 field1))))
          (append-text info (append ((ident->accu info) struct0)
                                    (wrap-as (i386:mem->accu))
                                    (wrap-as (i386:accu+value offset))))))
       ;; foo[i].bar.baz
       ((d-sel (ident ,field1) (d-sel (ident ,field0) (array-ref ,index (p-expr (ident ,array)))))
          (let* ((type0 (ident->type info array))
-                (type1 (field-type info `("struct" ,type0) field0))
-                (offset (+ (field-offset info `("struct" ,type0) field0)
-                           (field-offset info `("struct" ,type1) field1)))
+                (type1 (field-type info type0 field0))
+                (offset (+ (field-offset info type0 field0)
+                           (field-offset info type1 field1)))
                 (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array))))))
            (append-text info (wrap-as (i386:accu+value offset)))))
 
     ((decl-spec-list (type-qual ,qual) (type-spec (fixed-type ,type)))
      (ast-type->type info 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))
-     (ast-type->type info `("struct" ,type)))
+     (let ((struct (if (pair? type) type `("struct" ,type))))
+       (ast-type->type info struct)))
     ((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"))
     ((type-spec (typename ,type)) (ast-type->type info type))
     (_ (let ((type (get-type (.types info) o)))
     (type:size type)))
 
 (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)))
     (let loop ((fields fields))
       (if (null? fields) (error (format #f "no such field: ~a in ~s" field struct))
                   (else (loop (cdr fields)))))))))
 
 (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
         (let ((fields (type:description xtype)))
           (let loop ((fields fields) (offset 0))
                         (else (loop (cdr fields) (+ offset (field:size f))))))))))))
 
 (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
         (let ((field (field-field info struct field)))
           (field:size field)))))
 
 (define (field-type info struct field)
-  (let ((xtype (ast-type->type info struct)))
-        (let ((field (field-field info struct field)))
-          (field:type field))))
+  (let* ((struct (if (pair? struct) struct `("struct" ,struct)))
+         (xtype (ast-type->type info struct)))
+    (let ((field (field-field info struct field)))
+      (field:type field))))
 
 (define (ast->type o)
   (pmatch o
          (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)))))
-       (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)))))
-       (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)))))
-       (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)))))
-       (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))))
        ((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))))
        (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)))))
        `(union ,@(map (struct-field info) fields)))
index 8ca5cda96e5523dc629183a89904854421c0d9da..4e160c3c0b50a2275c5ceaa21c6bcc715b00a71f 100644 (file)
@@ -25,7 +25,12 @@ struct foo;
 
 struct foo* krak;
 
+#if 0
+//FIXME:  TODO
 typedef struct foo foo_struct;
+#else
+typedef struct foo foo;
+#endif
 
 struct foo
 {
@@ -47,8 +52,7 @@ typedef struct baz
 int
 test ()
 {
-  //struct foo f;
-  foo_struct f;
+  foo f;
   f.bar[0] = 0x22;
   f.bar[1] = 0x34;
   printf ("eentje: %d\n", f.bar[0]);
index 0ba86309ebc97e7f8c1c18e857960c91ce8fe2e0..57d9fe2847e5d0a2a21541db8fa6de9a1ba36e0c 100644 (file)
 #include "30-test.i"
 #include <stdio.h>
 
+union u {
+  int bar;
+  int baz;
+};
+
 struct foo
+{
+  union u u;
+};
+
+struct anon
 {
   union {
     int bar;
@@ -29,14 +39,21 @@ struct foo
   };
 };
 
+
 int
 test ()
 {
   struct foo f = {2};
-  printf ("f.bar=%d\n", f.bar);
-  if (f.bar != 2) return 1;
-  printf ("f.baz=%d\n", f.baz);
-  if (f.baz != 2) return 1;
+  printf ("f.u.bar=%d\n", f.u.bar);
+  if (f.u.bar != 2) return 1;
+  printf ("f.u.baz=%d\n", f.u.baz);
+  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;
 }