mescc: Do not dump variables with extern storage.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 27 Jul 2019 15:22:00 +0000 (17:22 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 27 Jul 2019 15:22:00 +0000 (17:22 +0200)
* lib/tests/scaffold/70-extern.stdout: New file.
* lib/tests/scaffold/70-extern.c: New file.
* build-aux/check-mescc.sh (TESTS): Add it..
* module/mescc/M1.scm (global-string?, global-extern?): New function.
(info->M1): Dump strings first.  Skip extern symbols.
* module/mescc/info.scm (<global>): Add storage field.
(make-global): Add storage parameter.  Pass it.
* module/mescc/compile.scm (make-global-entry): Likewise.
(global->info): Likewise.
(init-declr->info): Likewise.
(decl->info): Pass storage.

build-aux/check-mescc.sh
lib/tests/scaffold/70-extern.c [new file with mode: 0644]
lib/tests/scaffold/70-extern.stdout [new file with mode: 0644]
module/mescc/M1.scm
module/mescc/compile.scm
module/mescc/info.scm

index 0a3cb882be31a17c5064d3e180f27a9e44f941a6..53972e29d400c0322ff7977856f8874306dbe308 100755 (executable)
@@ -183,6 +183,7 @@ lib/tests/scaffold/7u-vstack.c
 lib/tests/scaffold/70-array-in-struct-init.c
 lib/tests/scaffold/70-struct-short-enum-init.c
 lib/tests/scaffold/70-struct-post.c
+lib/tests/scaffold/70-extern.c
 lib/tests/setjmp/80-setjmp.c
 lib/tests/stdio/80-sscanf.c
 lib/tests/stdlib/80-qsort.c
diff --git a/lib/tests/scaffold/70-extern.c b/lib/tests/scaffold/70-extern.c
new file mode 100644 (file)
index 0000000..c20268a
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * GNU Mes --- Maxwell Equations of Software
+ * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of GNU Mes.
+ *
+ * GNU Mes is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * GNU Mes is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <mes/lib.h>
+
+char foo[3] = "foo";
+extern int baz;
+char bar[4] = "bar";
+
+int
+main (void)
+{
+  foo[3] = ':';
+  oputs (foo);
+  return 0;
+}
diff --git a/lib/tests/scaffold/70-extern.stdout b/lib/tests/scaffold/70-extern.stdout
new file mode 100644 (file)
index 0000000..ed3b07f
--- /dev/null
@@ -0,0 +1 @@
+foo:bar
\ No newline at end of file
index 4d59ee8d9d50c3da41947507dd28342c6cd64447..667402306f6a6c04424c3d965985fe8abe405816 100644 (file)
           (display sep))
       (loop (cdr o)))))
 
+(define (global-string? o)
+  (and (pair? o) (pair? (car o)) (eq? (caar o) #:string)))
+
+(define (global-extern? o)
+  (and=> (global:storage o) (cut eq? <> 'extern)))
+
 (define* (info->M1 file-name o #:key align? verbose?)
   (let* ((functions (.functions o))
          (function-names (map car functions))
          (globals (.globals o))
-         (global-names (map car globals))
-         (strings (filter (lambda (g) (and (pair? g) (eq? (car g) #:string))) global-names))
+         (globals (filter (negate (compose global-extern? cdr)) globals))
+         (strings (filter global-string? globals))
+         (strings (map car strings))
          (reg-size (type:size (assoc-ref (.types o) "*"))))
     (define (string->label o)
       (let ((index (list-index (lambda (s) (equal? s o)) strings)))
       (display "\n\n:HEX2_data\n"))
     (when verbose?
       (display "M1: globals\n" (current-error-port)))
-    (for-each write-global globals)))
+    (for-each write-global (filter global-string? globals))
+    (for-each write-global (filter (negate global-string?) globals))))
index 22c5968ebd095eeb8c06da5af4814ed2d621717e..74a2defffee15031ff9148601989769ce513c624 100644 (file)
 (define (append-text info text)
   (clone info #:text (append (.text info) text)))
 
-(define (make-global-entry name type value)
-  (cons name (make-global name type value #f)))
+(define (make-global-entry name storage type value)
+  (cons name (make-global name type value storage #f)))
 
 (define (string->global-entry string)
   (let ((value (append (string->list string) (list #\nul))))
-   (make-global-entry `(#:string ,string) "char" value)))
+   (make-global-entry `(#:string ,string) '() "char" value)))
 
 (define (make-local-entry name type id)
   (cons name (make-local name type id)))
     (((decl-spec-list (type-spec ,type)) (init-declr-list . ,inits))
      (let* ((info (type->info type #f info))
             (type (ast->type type info)))
-       (fold (cut init-declr->info type <> <>) info (map cdr inits))))
+       (fold (cut init-declr->info type 'storage <> <>) info (map cdr inits))))
     (((decl-spec-list (type-spec ,type)))
      (type->info type #f info))
     (((decl-spec-list (stor-spec (typedef)) (type-spec ,type)) (init-declr-list (init-declr (ident ,name))))
      (let* ((info (type->info type #f info))
             (type (ast->type type info))
             (function (.function info)))
-       (if (not function) (fold (cut init-declr->info type <> <>) info (map cdr inits))
+       (if (not function) (fold (cut init-declr->info type store <> <>) info (map cdr inits))
            (let* ((tmp (clone info #:function #f #:globals '()))
-                  (tmp (fold (cut init-declr->info type <> <>) tmp (map cdr inits)))
+                  (tmp (fold (cut init-declr->info type store <> <>) tmp (map cdr inits)))
                   (statics (map (global->static function) (.globals tmp)))
                   (strings (filter string-global? (.globals tmp))))
              (clone info #:globals (append (.globals info) strings)
          (local (cdr local)))
     (init-local local init 0 info)))
 
-(define (global->info type name o init info)
+(define (global->info storage type name o init info)
   (let* ((rank (->rank type))
          (size (->size type info))
          (data (cond ((not init) (string->list (make-string size #\nul)))
                       (let* ((string (array-init->string init))
                              (size (or (and string (max size (1+ (string-length string))))
                                        size))
-                             (data  (or (and=> string string->list)
-                                        (array-init->data type size init info))))
+                             (data (or (and=> string string->list)
+                                       (array-init->data type size init info))))
                         (append data (string->list (make-string (max 0 (- size (length data))) #\nul)))))
                      ((structured-type? type)
                       (let ((data (init->data type init info)))
                      (else
                       (let ((data (init->data type init info)))
                         (append data (string->list (make-string (max 0 (- size (length data))) #\nul)))))))
-         (global (make-global-entry name type data)))
+         (global (make-global-entry name storage type data)))
     (clone info #:globals (append (.globals info) (list global)))))
 
 (define (array-init-element->data type o info)
                         (cdr o))))
     (_ #f)))
 
-(define (init-declr->info type o info)
+(define (init-declr->info type storage o info)
   (pmatch o
     (((ident ,name))
      (if (.function info) (local->info type name o #f info)
-         (global->info type name o #f info)))
+         (global->info storage type name o #f info)))
     (((ident ,name) (initzer ,init))
      (let* ((strings (init->strings init info))
             (info (if (null? strings) info
                       (clone info #:globals (append (.globals info) strings)))))
        (if (.function info) (local->info type name o init info)
-           (global->info type name o init info))))
+           (global->info storage type name o init info))))
     (((ftn-declr (ident ,name) . ,_))
      (let ((functions (.functions info)))
        (if (member name functions) info
      (let* ((rank (pointer->rank pointer))
             (type (rank+= type rank)))
        (if (.function info) (local->info type name o init info)
-           (global->info type name o init info))))
+           (global->info storage type name o init info))))
     (((ftn-declr (scope (ptr-declr ,pointer (ident ,name))) ,param-list))
      (let* ((rank (pointer->rank pointer))
             (type (rank+= type rank)))
        (if (.function info) (local->info type name o '() info)
-           (global->info type name o '() info))))
+           (global->info storage type name o '() info))))
     (((ptr-declr ,pointer . ,_) . ,init)
      (let* ((rank (pointer->rank pointer))
             (type (rank+= type rank)))
-       (init-declr->info type (append _ init) info)))
+       (init-declr->info type storage (append _ init) info)))
     (((array-of (ident ,name) ,count) . ,init)
      (let* ((strings (init->strings init info))
             (info (if (null? strings) info
             (count (expr->number info count))
             (type (make-c-array type count)))
        (if (.function info) (local->info type name o init info)
-           (global->info type name o init info))))
+           (global->info storage type name o init info))))
     (((array-of (ident ,name)) . ,init)
      (let* ((strings (init->strings init info))
             (info (if (null? strings) info
             (count (length (cadar init)))
             (type (make-c-array type count)))
        (if (.function info) (local->info type name o init info)
-           (global->info type name o init info))))
+           (global->info storage type name o init info))))
     ;; FIXME: recursion
     (((array-of (array-of (ident ,name) ,count1) ,count) . ,init)
      (let* ((strings (init->strings init info))
             (count1 (expr->number info count1))
             (type (make-c-array (make-c-array type count1) count)))
        (if (.function info) (local->info type name o init info)
-           (global->info type name o init info))))
+           (global->info storage type name o init info))))
     (_ (error "init-declr->info: not supported: " o))))
 
 (define (enum-def-list->constants constants fields)
index 49ce33ab7800eb793e2afb3135368f0afbdbe8ca..49a0974f8e62abdaa9f47cb05eb361af21a4fac7 100644 (file)
@@ -91,6 +91,7 @@
             global:c-array
             global:var
             global:value
+            global:storage
             global:function
             global->string
 
   (value var:value))
 
 (define-immutable-record-type <global>
-  (make-global- name type var value function)
+  (make-global- name type var value storage function)
   global?
   (name global:name)
   (type global:type)
   (var global:var)                      ; <var>
 
   (value global:value)
+  (storage global:storage)
   (function global:function))
 
-(define (make-global name type value function)
-  (make-global- name type (make-var name type function #f value) value function))
+(define (make-global name type value storage function)
+  (make-global- name type (make-var name type function #f value) value storage function))
 
 (define (global->string o)
   (or (and=> (global:function o) (cut string-append <> "-" (global:name o)))