This commit adds support for modules publicizing the exports of other
modules.  For example:

  module GRAMP =
      access pub GRAMP_Symbol,
             pub GRAMP_Word,
             pub GRAMP_Alphabet
  def pub string libgramp_version = "1.0";
      skip
  fed

Signed-off-by: Jose E. Marchesi <[email protected]>

gcc/algol68/ChangeLog

        * a68-parser-taxes.cc (tax_module_dec): Do not handle
        DEFINING_MODULE_INDICANT.
        * a68-exports.cc (a68_add_module_to_moif): Do not mangle module
        names in module extracts.
        (add_pub_revelations_to_moif): New function.
        (a68_do_exports): Simplify and call add_pub_revelations_to_moif.
        * a68-imports.cc (a68_decode_moifs): Add all decoded moifs to the
        global list TOP_MOIF.
        * a68-parser-extract.cc (extract_revelation): Recurse to import
        extracts from publicized modules.
        (a68_extract_indicants): Do not add symbol table entries for
        defining modules.
        * a68-types.h (struct TAG_T): Remove field EXPORTED.
        (EXPORTED): Remove macro.
        (TOP_MOIF): Define.
        * a68-parser.cc (a68_parser): Initialize global list of moifs.
        (a68_new_tag): Do not initialize EXPORTED.

gcc/testsuite/ChangeLog

        * algol68/execute/modules/module22bar.a68: New test.
        * algol68/execute/modules/module22foo.a68: Likewise.
        * algol68/execute/modules/program-22.a68: Likewise.
        * algol68/compile/modules/program-11.a68: Adjust test to
        publicized modules.
        * 
algol68/compile/modules/program-error-multiple-delaration-module-1.a68:
        Likewise.
---
 gcc/algol68/a68-exports.cc                    | 131 ++++++++++--------
 gcc/algol68/a68-imports.cc                    |  40 ++++--
 gcc/algol68/a68-parser-extract.cc             |  46 +++---
 gcc/algol68/a68-parser-taxes.cc               |  12 --
 gcc/algol68/a68-parser.cc                     |   2 +-
 gcc/algol68/a68-types.h                       |   8 +-
 .../algol68/compile/modules/program-11.a68    |   3 +-
 ...ram-error-multiple-delaration-module-1.a68 |   4 +-
 .../algol68/execute/modules/module22bar.a68   |   7 +
 .../algol68/execute/modules/module22foo.a68   |   4 +
 .../algol68/execute/modules/program-22.a68    |   6 +
 11 files changed, 152 insertions(+), 111 deletions(-)
 create mode 100644 gcc/testsuite/algol68/execute/modules/module22bar.a68
 create mode 100644 gcc/testsuite/algol68/execute/modules/module22foo.a68
 create mode 100644 gcc/testsuite/algol68/execute/modules/program-22.a68

diff --git a/gcc/algol68/a68-exports.cc b/gcc/algol68/a68-exports.cc
index ff4561f54a7..469e945cb42 100644
--- a/gcc/algol68/a68-exports.cc
+++ b/gcc/algol68/a68-exports.cc
@@ -131,10 +131,7 @@ static void
 a68_add_module_to_moif (MOIF_T *moif, TAG_T *tag)
 {
   EXTRACT_T *e = ggc_alloc<EXTRACT_T> ();
-  /* Module tags are not associated with declarations, so we have to do the
-     mangling here.  */
-  tree id = a68_get_mangled_indicant (NSYMBOL (NODE (tag)), NAME (moif));
-  const char *tag_symbol = IDENTIFIER_POINTER (id);
+  const char *tag_symbol = NSYMBOL (NODE (tag));
 
   EXTRACT_KIND (e) = GA68_EXTRACT_MODU;
   EXTRACT_SYMBOL (e) = ggc_strdup (tag_symbol);
@@ -525,6 +522,26 @@ a68_asm_output_moif (MOIF_T *moif)
     }
 }
 
+/* Add module exports for publicized module revelations.  */
+
+static void
+add_pub_revelations_to_moif (MOIF_T *moif, NODE_T *p)
+{
+  for (; p != NO_NODE; FORWARD (p))
+    {
+      if (IS (p, PUBLIC_SYMBOL))
+       {
+         gcc_assert (IS (NEXT (p), MODULE_INDICANT));
+         TAG_T *tag = a68_new_tag ();
+         NODE (tag) = NEXT (p);
+         a68_add_module_to_moif (moif, tag);
+         FORWARD (p);
+       }
+      else
+       add_pub_revelations_to_moif (moif, SUB (p));
+    }
+}
+
 /* Emit export information for the module definition in the parse tree P.  */
 
 void
@@ -534,65 +551,59 @@ a68_do_exports (NODE_T *p)
     {
       if (IS (p, DEFINING_MODULE_INDICANT))
        {
-         // XXX only do this if the defining module is to be
-         // exported. Accessed modules without PUB are not exported.  */
-         TAG_T *tag = a68_find_tag_global (TABLE (p), MODULE_SYMBOL, NSYMBOL 
(p));
-         gcc_assert (tag != NO_TAG);
+         tree module_id = a68_get_mangled_indicant (NSYMBOL (p));
+         MOIF_T *moif = a68_moif_new (IDENTIFIER_POINTER (module_id));
+         char *prelude = xasprintf ("%s__prelude", IDENTIFIER_POINTER 
(module_id));
+         char *postlude = xasprintf ("%s__postlude", IDENTIFIER_POINTER 
(module_id));
+         PRELUDE (moif) = ggc_strdup (prelude);
+         POSTLUDE (moif) = ggc_strdup (postlude);
+         free (prelude);
+         free (postlude);
+
+         NODE_T *module_text = NEXT (NEXT (p));
+         gcc_assert (IS (module_text, MODULE_TEXT));
+
+         /* Get modules exports from the revelation part.  */
+         if (IS (SUB (module_text), REVELATION_PART))
+           {
+             NODE_T *revelation_part = SUB (module_text);
+             add_pub_revelations_to_moif (moif, SUB (revelation_part));
+           }
 
-         if (EXPORTED (tag))
+         NODE_T *def_part = (IS (SUB (module_text), REVELATION_PART)
+                             ? NEXT_SUB (module_text)
+                             : SUB (module_text));
+         gcc_assert (IS (def_part, DEF_PART));
+         TABLE_T *table = TABLE (SUB (def_part));
+         gcc_assert (PUBLIC_RANGE (table));
+
+         for (TAG_T *t = INDICANTS (table); t != NO_TAG; FORWARD (t))
            {
-             tree module_id = a68_get_mangled_indicant (NSYMBOL (p));
-             MOIF_T *moif = a68_moif_new (IDENTIFIER_POINTER (module_id));
-             char *prelude = xasprintf ("%s__prelude", IDENTIFIER_POINTER 
(module_id));
-             char *postlude = xasprintf ("%s__postlude", IDENTIFIER_POINTER 
(module_id));
-             PRELUDE (moif) = ggc_strdup (prelude);
-             POSTLUDE (moif) = ggc_strdup (postlude);
-             free (prelude);
-             free (postlude);
-
-             NODE_T *module_text = NEXT (NEXT (p));
-             gcc_assert (IS (module_text, MODULE_TEXT));
-             NODE_T *def_part = (IS (SUB (module_text), REVELATION_PART)
-                                 ? NEXT_SUB (module_text)
-                                 : SUB (module_text));
-             gcc_assert (IS (def_part, DEF_PART));
-             TABLE_T *table = TABLE (SUB (def_part));
-             gcc_assert (PUBLIC_RANGE (table));
-
-             for (TAG_T *t = MODULES (table); t != NO_TAG; FORWARD (t))
-               {
-                 if (PUBLICIZED (t))
-                   a68_add_module_to_moif (moif, t);
-               }
-
-             for (TAG_T *t = INDICANTS (table); t != NO_TAG; FORWARD (t))
-               {
-                 if (PUBLICIZED (t))
-                   a68_add_indicant_to_moif (moif, t);
-               }
-
-             for (TAG_T *t = IDENTIFIERS (table); t != NO_TAG; FORWARD (t))
-               {
-                 if (PUBLICIZED (t))
-                   a68_add_identifier_to_moif (moif, t);
-               }
-
-             for (TAG_T *t = PRIO (table); t != NO_TAG; FORWARD (t))
-               {
-                 if (PUBLICIZED (t))
-                   a68_add_prio_to_moif (moif, t);
-               }
-
-             for (TAG_T *t = OPERATORS (table); t != NO_TAG; FORWARD (t))
-               {
-                 if (PUBLICIZED (t))
-                   a68_add_operator_to_moif (moif, t);
-               }
-
-             a68_asm_output_moif (moif);
-             if (flag_a68_dump_moif)
-               a68_dump_moif (moif);
+             if (PUBLICIZED (t))
+               a68_add_indicant_to_moif (moif, t);
            }
+
+         for (TAG_T *t = IDENTIFIERS (table); t != NO_TAG; FORWARD (t))
+           {
+             if (PUBLICIZED (t))
+               a68_add_identifier_to_moif (moif, t);
+           }
+
+         for (TAG_T *t = PRIO (table); t != NO_TAG; FORWARD (t))
+           {
+             if (PUBLICIZED (t))
+               a68_add_prio_to_moif (moif, t);
+           }
+
+         for (TAG_T *t = OPERATORS (table); t != NO_TAG; FORWARD (t))
+           {
+             if (PUBLICIZED (t))
+               a68_add_operator_to_moif (moif, t);
+           }
+
+         a68_asm_output_moif (moif);
+         if (flag_a68_dump_moif)
+           a68_dump_moif (moif);
        }
       else
        a68_do_exports (SUB (p));
diff --git a/gcc/algol68/a68-imports.cc b/gcc/algol68/a68-imports.cc
index 775d58c0715..ff117163e15 100644
--- a/gcc/algol68/a68-imports.cc
+++ b/gcc/algol68/a68-imports.cc
@@ -1286,11 +1286,11 @@ a68_decode_extracts (MOIF_T *moif, encoded_modes_map_t 
&encoded_modes,
   return false;
 }
 
-/* Decode the given exports data into a linked list of moifs.  If there is a
-   decoding error then put an explicative mssage in *ERRSTR and return
-   NULL.  */
+/* Decode the given exports data into moifs, add them to the TOP_MOIF list, and
+   return true.  If there is a decoding error then put an explicative message
+   in *ERRSTR and return false.  */
 
-static MOIF_T *
+static bool
 a68_decode_moifs (const char *data, size_t size, const char **errstr)
 {
   MOIF_T *moif_list = NO_MOIF;
@@ -1349,12 +1349,25 @@ a68_decode_moifs (const char *data, size_t size, const 
char **errstr)
        }
     }
 
-  /* Got some juicy exports for youuuuuu... */
-  return moif_list;
+  /* Add the moifs in moif_list to the global list of moifs.  */
+  /* XXX error and fail on duplicates?  */
+  {
+    MOIF_T *end = TOP_MOIF (&A68_JOB);
+    if (end == NO_MOIF)
+      TOP_MOIF (&A68_JOB) = moif_list;
+    else
+      {
+       while (NEXT (end) != NO_MOIF)
+         FORWARD (end);
+       NEXT (end) = moif_list;
+      }
+  }
+
+  return true;
  decode_error:
   if (*errstr == NULL)
     *errstr = "premature end of data";
-  return NULL;
+  return false;
 }
 
 /* Get a moif with the exports for module named MODULE.  If no exports can be
@@ -1395,11 +1408,16 @@ a68_open_packet (const char *module)
 
   /* Got some data.  Decode it into a list of moif.  */
   const char *errstr = NULL;
-  MOIF_T *moif = a68_decode_moifs (exports_data, exports_data_size, &errstr);
+  if (!a68_decode_moifs (exports_data, exports_data_size, &errstr))
+    {
+      a68_error (NO_NODE, "%s", errstr);
+      return NULL;
+    }
 
-  /* The moif we are looking for must be in the list.  Note these are garbage
-     collected.  */
+  /* The androids we are looking for are likely to be now in the global
+     list.  */
+  MOIF_T *moif = TOP_MOIF (&A68_JOB);
   while (moif != NO_MOIF && strcmp (NAME (moif), module) != 0)
-    moif = NEXT (moif);
+    FORWARD (moif);
   return moif;
 }
diff --git a/gcc/algol68/a68-parser-extract.cc 
b/gcc/algol68/a68-parser-extract.cc
index 51ccc89986c..f02ae6db322 100644
--- a/gcc/algol68/a68-parser-extract.cc
+++ b/gcc/algol68/a68-parser-extract.cc
@@ -185,23 +185,30 @@ skip_pack_declarer (NODE_T *p)
     return p;
 }
 
-/* Extract a revelation.  */
+/* Extract the revelation associated with the module MODULE.  The node Q is
+   used for symbol table and diagnostic purposes.  Publicized modules are
+   recursively extracted as well.  This call may result in one or more
+   errors.  */
 
 static void
-extract_revelation (NODE_T *q, bool is_public ATTRIBUTE_UNUSED)
+extract_revelation (NODE_T *q, const char *module, TAG_T *tag)
 {
-  /* Store in the symbol table.  */
-  TAG_T *tag = a68_add_tag (TABLE (q), MODULE_SYMBOL, q, NO_MOID, STOP);
-  gcc_assert (tag != NO_TAG);
-  EXPORTED (tag) = false; // XXX depends on PUB!
   /* Import the MOIF and install it in the tag.  */
-  MOIF_T *moif = a68_open_packet (NSYMBOL (q));
+  MOIF_T *moif = a68_open_packet (module);
   if (moif == NULL)
     {
-      a68_error (q, "cannot find module Z", NSYMBOL (q));
+      a68_error (q, "cannot find module Z", module);
       return;
     }
-  MOIF (tag) = moif; // XXX add to existing list of moifs.
+
+  if (tag != NO_TAG)
+    MOIF (tag) = moif;
+
+  /* First thing to do is to extract the revelations of publicized modules in
+     this moif.  This leads to recursive calls of this function.  */
+
+  for (EXTRACT_T *e : MODULES (moif))
+    extract_revelation (q, EXTRACT_SYMBOL (e), NO_TAG);
 
   /* Store all the modes from the MOIF in the moid list.
 
@@ -345,18 +352,26 @@ a68_extract_indicants (NODE_T *p)
              FORWARD (q);
              if (q != NO_NODE)
                {
+                 NODE_T *bold_tag = NO_NODE;
+
                  if (IS (q, BOLD_TAG))
                    {
-                     extract_revelation (q, false /* is_public */);
+                     bold_tag = q;
                      FORWARD (q);
                    }
                  else if (a68_whether (q, PUBLIC_SYMBOL, BOLD_TAG, STOP))
                    {
-                     NODE_T *pub_node = q;
-                     extract_revelation (NEXT (pub_node), true /* is_public 
*/);
+                     bold_tag = NEXT (q);
                      FORWARD (q);
                      FORWARD (q);
                    }
+
+                 if (bold_tag != NO_NODE)
+                   {
+                     TAG_T *tag = a68_add_tag (TABLE (bold_tag), 
MODULE_SYMBOL, bold_tag, NO_MOID, STOP);
+                     gcc_assert (tag != NO_TAG);
+                     extract_revelation (bold_tag, NSYMBOL (bold_tag), tag);
+                   }
                }
            }
          while (q != NO_NODE && IS (q, COMMA_SYMBOL));
@@ -370,14 +385,7 @@ a68_extract_indicants (NODE_T *p)
              detect_redefined_keyword (q, MODULE_DECLARATION);
              if (a68_whether (q, BOLD_TAG, EQUALS_SYMBOL, STOP))
                {
-                 /* Store in the symbol table.
-                    XXX also add to global list of modules?
-                    Position of definition (q) connects to this lexical
-                    level!  */
                  ATTRIBUTE (q) = DEFINING_MODULE_INDICANT;
-                 TAG_T *tag = a68_add_tag (TABLE (p), MODULE_SYMBOL, q, 
NO_MOID, STOP);
-                 gcc_assert (tag != NO_TAG);
-                 EXPORTED (tag) = true;
                  FORWARD (q);
                  ATTRIBUTE (q) = EQUALS_SYMBOL; /* XXX why not 
ALT_EQUALS_SYMBOL */
                  if (NEXT (q) != NO_NODE && IS (NEXT (q), ACCESS_SYMBOL))
diff --git a/gcc/algol68/a68-parser-taxes.cc b/gcc/algol68/a68-parser-taxes.cc
index e5fde05e4fd..365cb66d59a 100644
--- a/gcc/algol68/a68-parser-taxes.cc
+++ b/gcc/algol68/a68-parser-taxes.cc
@@ -1188,18 +1188,6 @@ tax_module_dec (NODE_T *p)
        {
          tax_module_dec (NEXT (p));
        }
-      else if (IS (p, DEFINING_MODULE_INDICANT))
-       {
-         TAG_T *entry = MODULES (TABLE (p));
-         while (entry != NO_TAG && NODE (entry) != p)
-           FORWARD (entry);
-         MOID (p) = NO_MOID;
-         TAX (p) = entry;
-         HEAP (entry) = LOC_SYMBOL;
-         MOID (entry) = NO_MOID;
-         PUBLICIZED (entry) = PUBLICIZED (p);
-         tax_module_dec (NEXT (p));
-       }
       else
        {
          tax_tags (p);
diff --git a/gcc/algol68/a68-parser.cc b/gcc/algol68/a68-parser.cc
index e49e0873b21..725a8fc44de 100644
--- a/gcc/algol68/a68-parser.cc
+++ b/gcc/algol68/a68-parser.cc
@@ -446,6 +446,7 @@ a68_parser (const char *filename)
   A68_PARSER (error_tag) = (TAG_T *) a68_new_tag ();
   TOP_NODE (&A68_JOB) = NO_NODE;
   TOP_MOID (&A68_JOB) = NO_MOID;
+  TOP_MOIF (&A68_JOB) = NO_MOIF;
   TOP_LINE (&A68_JOB) = NO_LINE;
   STANDENV_MOID (&A68_JOB) = NO_MOID;
   a68_set_up_tables ();
@@ -784,7 +785,6 @@ a68_new_tag (void)
   VARIABLE (z) = false;
   IS_RECURSIVE (z) = false;
   PUBLICIZED (z) = true; /* XXX */
-  EXPORTED (z) = false;
   ASCRIBED_ROUTINE_TEXT (z) = false;
   LOWERER (z) = NO_LOWERER;
   TAX_TREE_DECL (z) = NULL_TREE;
diff --git a/gcc/algol68/a68-types.h b/gcc/algol68/a68-types.h
index 859f4148266..788e7230f92 100644
--- a/gcc/algol68/a68-types.h
+++ b/gcc/algol68/a68-types.h
@@ -585,9 +585,6 @@ struct GTY(()) TABLE_T
    PUBLICIZED is set for tags that are marked as public and therefore shall be
    exported as part of a module interface.
 
-   EXPORTED is set for DEFINING_MODULEs whose module interface is to be
-   exported.
-
    ASCRIBED_ROUTINE_TEXT is set when the defining identifier is ascribed a
    routine-text in an identity declaration.
 
@@ -621,7 +618,7 @@ struct GTY((chain_next ("%h.next"))) TAG_T
   NODE_T *node, *unit;
   const char *value;
   bool scope_assigned, use, in_proc, loc_assigned, portable, variable;
-  bool ascribed_routine_text, is_recursive, publicized, exported;
+  bool ascribed_routine_text, is_recursive, publicized;
   int priority, heap, scope, youngest_environ, number;
   STATUS_MASK_T status;
   tree tree_decl;
@@ -645,6 +642,7 @@ struct GTY(()) MODULE_T
   int error_count, warning_count, source_scan;
   LINE_T *top_line;
   MOID_T *top_moid, *standenv_moid;
+  MOIF_T *top_moif;
   NODE_T *top_node;
   OPTIONS_T options;
   FILE * GTY ((skip)) file_source_fd;
@@ -930,7 +928,6 @@ struct GTY(()) A68_T
 #define EQUIVALENT(p) ((p)->equivalent_mode)
 #define EQUIVALENT_MODE(p) ((p)->equivalent_mode)
 #define ERROR_COUNT(p) ((p)->error_count)
-#define EXPORTED(p) ((p)->exported)
 #define EXTERN_SYMBOL(p) ((p)->extern_symbol)
 #define EXTRACT_IN_PROC(p) ((p)->in_proc)
 #define EXTRACT_KIND(p) ((p)->kind)
@@ -1097,6 +1094,7 @@ struct GTY(()) A68_T
 #define TEXT(p) ((p)->text)
 #define TOP_LINE(p) ((p)->top_line)
 #define TOP_MOID(p) ((p)->top_moid)
+#define TOP_MOIF(p) ((p)->top_moif)
 #define TOP_NODE(p) ((p)->top_node)
 #define TRANSIENT(p) ((p)->transient)
 #define TREE_LISTING_SAFE(p) ((p)->tree_listing_safe)
diff --git a/gcc/testsuite/algol68/compile/modules/program-11.a68 
b/gcc/testsuite/algol68/compile/modules/program-11.a68
index 9da676df703..def57235c08 100644
--- a/gcc/testsuite/algol68/compile/modules/program-11.a68
+++ b/gcc/testsuite/algol68/compile/modules/program-11.a68
@@ -4,8 +4,7 @@
   inside controlled clauses in access clauses with
   several revelations.  }
 
-access Module10,
-       Module11,
+access Module11,
        Module12
 begin assert (foo = 10);
       assert (bar = "foo") { dg-error "" }
diff --git 
a/gcc/testsuite/algol68/compile/modules/program-error-multiple-delaration-module-1.a68
 
b/gcc/testsuite/algol68/compile/modules/program-error-multiple-delaration-module-1.a68
index 39ce7fe2b0f..562ec4cbd2b 100644
--- 
a/gcc/testsuite/algol68/compile/modules/program-error-multiple-delaration-module-1.a68
+++ 
b/gcc/testsuite/algol68/compile/modules/program-error-multiple-delaration-module-1.a68
@@ -1,7 +1,9 @@
 { dg-modules "module10 module11 module12" }
 
+{ Note how Module11 also exports the foo from Module10.  }
+
 access Module10,
-       Module11,
+       Module11, { dg-error "multiple declaration.*foo" }
        Module11 { dg-error "multiple declaration.*bar" }
 begin assert (foo = 10);
       assert (bar = 20)
diff --git a/gcc/testsuite/algol68/execute/modules/module22bar.a68 
b/gcc/testsuite/algol68/execute/modules/module22bar.a68
new file mode 100644
index 00000000000..7e56a03b02a
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/module22bar.a68
@@ -0,0 +1,7 @@
+module Module22Bar = access pub Module22Foo
+def
+    puts ("bar prelude'n");
+    pub int bar = foo + 10;
+    skip
+fed
+
diff --git a/gcc/testsuite/algol68/execute/modules/module22foo.a68 
b/gcc/testsuite/algol68/execute/modules/module22foo.a68
new file mode 100644
index 00000000000..e4727e40e93
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/module22foo.a68
@@ -0,0 +1,4 @@
+module Module22Foo =
+def pub int foo = 10;
+    skip
+fed
diff --git a/gcc/testsuite/algol68/execute/modules/program-22.a68 
b/gcc/testsuite/algol68/execute/modules/program-22.a68
new file mode 100644
index 00000000000..3523366d26f
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/program-22.a68
@@ -0,0 +1,6 @@
+{ dg-modules "module22foo module22bar" }
+
+access Module22Bar
+begin assert (foo = 10);
+      assert (bar = 20)
+end
-- 
2.30.2

Reply via email to