public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/modula-2] Bugfix -fm2-whole-program linking.
@ 2022-11-15 19:13 Gaius Mulley
  0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2022-11-15 19:13 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5c95b7e7dca8a41998a359439a3bf3b0e428ea72

commit 5c95b7e7dca8a41998a359439a3bf3b0e428ea72
Author: Gaius Mulley <gaiusmod2@gmail.com>
Date:   Tue Nov 15 19:07:18 2022 +0000

    Bugfix -fm2-whole-program linking.
    
    Linking a project using -fm2-whole-program would fail under the new
    linking schema.  The bugfixes here fix them.  The problem was that the
    naming of the dtor/ctor/init/fini functions (for outer modules) must
    not get name mangled.  Ensure that the special variables exported from
    M2LINK are only created once.  Subsequent attempts return with the
    existing variables.  Also fixed an obvious attribute name.  Allow
    the ZTYPE to be compared to WORD and BYTE without requiring a cast.
    Definition for "C" no longer automatically implies export unqualified.
    
    gcc/m2/ChangeLog:
    
            * Make-lang.in (CPP_GM2): Removed.  -fpermissive removed.
            Ensure that M2LINK.o is linked in to stage1/m2/cc1gm2.
            * gm2-compiler/M2Base.mod: Allow the ZTYPE to be compared
            to WORD and BYTE without requiring a cast.
            * gm2-compiler/M2AsmUtil.mod (SymbolTable): Import list added
            identifiers IsExtern, IsMonoName and IsPublic.
            (StringToKey): Reformatted.  (GetFullScopeAsmName): Rewritten.
            * gm2-compiler/M2Base.mod: Allow the ZTYPE to be compared
            to WORD and BYTE without requiring a cast.
            * gm2-compiler/M2Batch.mod: Improved comment.
            * gm2-compiler/M2GCCDeclare.def (DeclareM2linkGlobals):
            Add to export list.
            * gm2-compiler/M2GCCDeclare.mod: Ensure that
            DeclareModuleInit is called when -fm2-whole-program is
            employed.
            (DoVariableDeclaration) check to see if the special M2LINK
            variables require an initial value.  (AddEntryM2Link) New
            procedure.  (GetEntryM2Link) New procedure function.
            (DeclareM2linkGlobals) New procedure.  (DetectM2LinkInitial)
            New procedure.  (DeclareVariableWholeProgram) Rewritten.
            (InitM2LinkModule) New procedure.
            * gm2-compiler/M2GenGCC.mod: Call to DeclareM2linkGlobals
            change parameters.
            * gm2-compiler/M2Quad.mod (BuildTry): New procedure.
            (BuildExcept) New procedure.  (BuildM2MainFunction) create
            try/catch around _M2_init/_M2_fini providing exceptions
            are allowed.
            * gm2-compiler/M2Scaffold.mod: Add extra parameter to calls to
            PutModuleCtorExtern.  Call PutMonoName for all
            init/fini/link/main functions.  (initialized) New variable.
            * gm2-compiler/P1SymBuild.mod: Changed behaviour of
            definition for "C" to be consistant and the same as the
            bootstrap tool mc.  Definition for "C" no longer
            automatically implies export unqualified.
            * gm2-compiler/P2Build.bnf: Corrected ident comparison
            to unused.
            * gm2-compiler/SymbolTable.def: New definitions for
            IsMonoName and PutMonoName.
            * gm2-compiler/SymbolTable.mod: (IsMonoName) New procedure
            function.  (PutMonoName) New procedure.  ctor, init,
            fini, dep use MonoName as appropriate.
            (PutModuleCtorExtern): Add new parameter.
            (MakeProcedure): Initialize IsMonoName.
            * gm2-gcc/init.cc: Remove declarations for M2LINK
            variables.
            * gm2-gcc/m2decl.def (DeclareM2linkForcedModuleInitOrder)
            New procedure.  (DeclareM2linkStaticInitialization) New
            procedure.  (BuildPtrToTypeString) New function.
            * tools-src/boilerplate.py: Change all double quotes to
            single quotes.
            * tools-src/def2doc.py: Change all double quotes to
            single quotes.
    
    gcc/testsuite/gm2/ChangeLog:
    
            * calling-c/datatypes/unbounded/run/pass/c.def: Add
            EXPORT UNQUALIFIED.
            * examples/callingC/run/pass/c.def: Add EXPORT
            UNQUALIFIED.
            * extensions/run/pass/cvararg.def: Add EXPORT
            UNQUALIFIED.
            * pim/run/pass/minhello.mod: New file.
            * switches/check-all/run/fail/tinyrange.mod: New file.
            * switches/whole-program/pass/run/hello.mod: New file.
            * switches/whole-program/pass/run/hello2.mod: New file.
    
    Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>

Diff:
---
 gcc/m2/Make-lang.in                                |  34 +--
 gcc/m2/Make-maintainer.in                          |  16 ++
 gcc/m2/gm2-compiler/M2AsmUtil.def                  |   4 +-
 gcc/m2/gm2-compiler/M2AsmUtil.mod                  |  49 +++--
 gcc/m2/gm2-compiler/M2Base.mod                     |   4 +-
 gcc/m2/gm2-compiler/M2Batch.mod                    |   3 +-
 gcc/m2/gm2-compiler/M2GCCDeclare.def               |  10 +
 gcc/m2/gm2-compiler/M2GCCDeclare.mod               | 205 +++++++++++++----
 gcc/m2/gm2-compiler/M2GenGCC.mod                   |  13 +-
 gcc/m2/gm2-compiler/M2Quads.mod                    |  73 +++++-
 gcc/m2/gm2-compiler/M2Scaffold.mod                 |  33 ++-
 gcc/m2/gm2-compiler/P1SymBuild.mod                 |   7 +-
 gcc/m2/gm2-compiler/P2Build.bnf                    |   2 +-
 gcc/m2/gm2-compiler/SymbolTable.def                |  17 +-
 gcc/m2/gm2-compiler/SymbolTable.mod                |  74 ++++++-
 gcc/m2/gm2-gcc/init.cc                             |  11 +-
 gcc/m2/gm2-gcc/m2decl.cc                           |  57 +++--
 gcc/m2/gm2-gcc/m2decl.def                          |  18 +-
 gcc/m2/gm2-gcc/m2decl.h                            |  10 +-
 gcc/m2/tools-src/boilerplate.py                    | 244 ++++++++++-----------
 gcc/m2/tools-src/def2doc.py                        | 139 +++++++++---
 .../calling-c/datatypes/unbounded/run/pass/c.def   |   2 +
 gcc/testsuite/gm2/examples/callingC/run/pass/c.def |   2 +
 gcc/testsuite/gm2/extensions/run/pass/cvararg.def  |   2 +
 gcc/testsuite/gm2/pim/run/pass/minhello.mod        |  12 +
 .../gm2/switches/check-all/run/fail/tinyrange.mod  |  17 ++
 .../gm2/switches/whole-program/pass/run/hello.mod  |   7 +
 .../gm2/switches/whole-program/pass/run/hello2.mod |   7 +
 28 files changed, 749 insertions(+), 323 deletions(-)

diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in
index 9b030473750..103e62f8584 100644
--- a/gcc/m2/Make-lang.in
+++ b/gcc/m2/Make-lang.in
@@ -27,7 +27,6 @@ GM2_CROSS_NAME = `echo gm2|sed '$(program_transform_cross_name)'`
 
 M2_MAINTAINER = no
 
-CPP_GM2=-fpermissive -DIN_GCC -g
 GM2_1 = ./gm2 -B./stage1/m2 -g -fm2-g
 
 GM2_FOR_TARGET = $(STAGE_CC_WRAPPER) ./gm2 -B./ -B$(build_tooldir)/bin/ -L$(objdir)/../ld $(TFLAGS)
@@ -431,33 +430,18 @@ GM2_LIBS          = m2/gm2-compiler/gm2.a \
 GM2_LIBS_BOOT     = m2/gm2-compiler-boot/gm2.a \
                     m2/gm2-libs-boot/libgm2.a \
                     $(GM2-BOOT-O)
-GM2_LIBS_PARANOID = m2/gm2-compiler-paranoid/gm2.a \
-                    m2/gm2-libs-paranoid/libgm2.a                       # build it again using GM2_LIBS
-
-gm2.paranoid: stage3/m2/cc1gm2$(exeext) gm2.verifyparanoid
 
 cc1gm2$(exeext): stage1/m2/cc1gm2$(exeext) $(m2.prev)
 	cp -p $< $@
 
-stage3/m2/cc1gm2$(exeext): stage2/m2/cc1gm2$(exeext) m2/gm2-compiler-paranoid/m2flex.o \
-                            $(P) $(GM2_C_OBJS) $(BACKEND) $(LIBDEPS) $(GM2_LIBS_PARANOID) \
-                            m2/gm2-gcc/rtegraph.o plugin/m2rte$(exeext).so
-	@$(call LINK_PROGRESS,$(INDEX.m2),start)
-	+$(LLINKER) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GM2_C_OBJS) m2/gm2-compiler-paranoid/m2flex.o \
-                            attribs.o \
-                              $(GM2_LIBS_PARANOID) \
-                              $(BACKEND) $(LIBS) m2/gm2-gcc/rtegraph.o \
-                              $(BACKENDLIBS) $(LIBSTDCXX) -lm
-	@$(call LINK_PROGRESS,$(INDEX.m2),end)
-
 stage2/m2/cc1gm2$(exeext): stage1/m2/cc1gm2$(exeext) m2/gm2-compiler/m2flex.o $(P) \
                             $(GM2_C_OBJS) $(BACKEND) $(LIBDEPS) $(GM2_LIBS) \
-                            m2/gm2-gcc/rtegraph.o plugin/m2rte$(exeext).so
+                            m2/gm2-gcc/rtegraph.o plugin/m2rte$(exeext).so m2/gm2-libs-boot/M2LINK.o
 	@$(call LINK_PROGRESS,$(INDEX.m2),start)
 	+$(LLINKER) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GM2_C_OBJS) m2/gm2-compiler/m2flex.o \
                             attribs.o \
                               $(GM2_LIBS) \
-                              $(BACKEND) $(LIBS) m2/gm2-gcc/rtegraph.o \
+                              $(BACKEND) $(LIBS) m2/gm2-gcc/rtegraph.o m2/gm2-libs-boot/M2LINK.o \
                               $(BACKENDLIBS) $(LIBSTDCXX) -lm
 	@$(call LINK_PROGRESS,$(INDEX.m2),end)
 
@@ -1291,11 +1275,11 @@ mcflex.c: $(srcdir)/m2/mc/mc.flex
 
 m2/gm2-libs-boot/%.o: $(srcdir)/m2/gm2-libs-boot/%.mod $(MCDEPS) $(BUILD-BOOT-H)
 	$(MC) -o=m2/gm2-libs-boot/$*.c $(srcdir)/m2/gm2-libs-boot/$*.mod
-	$(COMPILER) -c $(CPP_GM2) $(CFLAGS) $(MCINCLUDES) m2/gm2-libs-boot/$*.c -o $@
+	$(COMPILER) -c -DIN_GCC $(CFLAGS) $(MCINCLUDES) m2/gm2-libs-boot/$*.c -o $@
 
 m2/gm2-libs-boot/%.o: $(srcdir)/m2/gm2-libs/%.mod $(MCDEPS) $(BUILD-BOOT-H)
 	$(MC) -o=m2/gm2-libs-boot/$*.c $(srcdir)/m2/gm2-libs/$*.mod
-	$(COMPILER) -c $(CPP_GM2) $(CFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/$*.c -o $@
+	$(COMPILER) -c -DIN_GCC $(CFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/$*.c -o $@
 
 m2/gm2-libs-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-libs/%.def $(MCDEPS)
 	$(MC) -o=$@ $(srcdir)/m2/gm2-libs/$*.def
@@ -1336,34 +1320,34 @@ m2/gm2-libs-boot/SysExceptions.o: $(srcdir)/m2/gm2-libs-ch/SysExceptions.c \
 
 m2/gm2-libs-boot/SysStorage.o: $(srcdir)/m2/gm2-libs/SysStorage.mod $(MCDEPS) $(BUILD-BOOT-H)
 	$(MC) -o=m2/gm2-libs-boot/SysStorage.c $(srcdir)/m2/gm2-libs/SysStorage.mod
-	$(COMPILER) -DIN_GCC -c -fpermissive $(CFLAGS) \
+	$(COMPILER) -DIN_GCC -c $(CFLAGS) \
           -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) \
           m2/gm2-libs-boot/SysStorage.c -o m2/gm2-libs-boot/SysStorage.o
 
 m2/gm2-compiler-boot/M2GCCDeclare.o: $(srcdir)/m2/gm2-compiler/M2GCCDeclare.mod $(MCDEPS) $(BUILD-BOOT-H)
 	$(MC) --extended-opaque -o=m2/gm2-compiler-boot/M2GCCDeclare.c $<
-	$(COMPILER) -c -fpermissive $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/M2GCCDeclare.c -o $@
 
 m2/gm2-compiler-boot/M2Error.o: $(srcdir)/m2/gm2-compiler/M2Error.mod $(MCDEPS) $(BUILD-BOOT-H)
 	$(MC) --extended-opaque -o=m2/gm2-compiler-boot/M2Error.c $<
-	$(COMPILER) -c -fpermissive $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/M2Error.c -o $@
 
 m2/gm2-compiler-boot/%.o: $(srcdir)/m2/gm2-compiler/%.mod $(BUILD-BOOT-H) $(MCDEPS) $(BUILD-BOOT-H)
 	$(MC) -o=m2/gm2-compiler-boot/$*.c $(srcdir)/m2/gm2-compiler/$*.mod
-	$(COMPILER) -c -fpermissive $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot -Im2/gm2-libiberty \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/$*.c -o $@
 
 m2/gm2-compiler-boot/%.o: m2/gm2-compiler-boot/%.mod $(MCDEPS) $(BUILD-BOOT-H)
 	$(MC) -o=m2/gm2-compiler-boot/$*.c m2/gm2-compiler-boot/$*.mod
-	$(COMPILER) -c -fpermissive $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/$*.c -o $@
diff --git a/gcc/m2/Make-maintainer.in b/gcc/m2/Make-maintainer.in
index c0491121fae..8a477226760 100644
--- a/gcc/m2/Make-maintainer.in
+++ b/gcc/m2/Make-maintainer.in
@@ -604,6 +604,22 @@ GM2-VERIFY-MODS    = FifoQueue.mod     M2AsmUtil.mod                   M2Optimiz
 GM2-VERIFY-AUTO    = P1Build.mod       P2Build.mod     PCBuild.mod     P3Build.mod     \
                      PHBuild.mod       pg.mod          P0SyntaxCheck.mod
 
+GM2_LIBS_PARANOID = m2/gm2-compiler-paranoid/gm2.a \
+                    m2/gm2-libs-paranoid/libgm2.a                       # build it again using GM2_LIBS
+
+gm2.paranoid: stage3/m2/cc1gm2$(exeext) gm2.verifyparanoid
+
+stage3/m2/cc1gm2$(exeext): stage2/m2/cc1gm2$(exeext) m2/gm2-compiler-paranoid/m2flex.o \
+                            $(P) $(GM2_C_OBJS) $(BACKEND) $(LIBDEPS) $(GM2_LIBS_PARANOID) \
+                            m2/gm2-gcc/rtegraph.o plugin/m2rte$(exeext).so m2/gm2-libs-boot/M2LINK.o
+	@$(call LINK_PROGRESS,$(INDEX.m2),start)
+	+$(LLINKER) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GM2_C_OBJS) m2/gm2-compiler-paranoid/m2flex.o \
+                            attribs.o \
+                              $(GM2_LIBS_PARANOID) \
+                              $(BACKEND) $(LIBS) m2/gm2-gcc/rtegraph.o m2/gm2-libs-boot/M2LINK.o \
+                              $(BACKENDLIBS) $(LIBSTDCXX) -lm
+	@$(call LINK_PROGRESS,$(INDEX.m2),end)
+
 
 # gm2.verifyparanoid diffs the output of all three compilers with the compiler source code
 
diff --git a/gcc/m2/gm2-compiler/M2AsmUtil.def b/gcc/m2/gm2-compiler/M2AsmUtil.def
index 6369823e94c..ab93f320de1 100644
--- a/gcc/m2/gm2-compiler/M2AsmUtil.def
+++ b/gcc/m2/gm2-compiler/M2AsmUtil.def
@@ -40,7 +40,7 @@ EXPORT QUALIFIED GetFullSymName, GetFullScopeAsmName ;
                     GetAsmName except that it does not have the leading _
 *)
 
-PROCEDURE GetFullSymName (Sym: CARDINAL) : Name ;
+PROCEDURE GetFullSymName (sym: CARDINAL) : Name ;
 
 
 (*
@@ -49,7 +49,7 @@ PROCEDURE GetFullSymName (Sym: CARDINAL) : Name ;
                          [DefImpModule|Module]_{InnerModule}_{Procedure}_SymbolName
 *)
 
-PROCEDURE GetFullScopeAsmName (Sym: CARDINAL) : Name ;
+PROCEDURE GetFullScopeAsmName (sym: CARDINAL) : Name ;
 
 
 END M2AsmUtil.
diff --git a/gcc/m2/gm2-compiler/M2AsmUtil.mod b/gcc/m2/gm2-compiler/M2AsmUtil.mod
index cfaef418e02..7fc54cd22ed 100644
--- a/gcc/m2/gm2-compiler/M2AsmUtil.mod
+++ b/gcc/m2/gm2-compiler/M2AsmUtil.mod
@@ -40,7 +40,7 @@ FROM SymbolTable IMPORT NulSym,
                         IsModule,
                         IsDefImp,
                         IsExportQualified,
-                        IsExported,
+                        IsExported, IsPublic, IsExtern, IsMonoName,
                         IsDefinitionForC ;
 
 FROM M2Error IMPORT InternalError ;
@@ -55,9 +55,9 @@ PROCEDURE StringToKey (s: String) : Name ;
 VAR
    k: Name ;
 BEGIN
-   k := makekey(string(s)) ;
-   s := KillString(s) ;
-   RETURN( k )
+   k := makekey (string (s)) ;
+   s := KillString (s) ;
+   RETURN k
 END StringToKey ;
 
 
@@ -67,21 +67,27 @@ END StringToKey ;
                          [DefImpModule|Module]_{InnerModule}_{Procedure}_SymbolName
 *)
 
-PROCEDURE GetFullScopeAsmName (Sym: CARDINAL) : Name ;
+PROCEDURE GetFullScopeAsmName (sym: CARDINAL) : Name ;
 VAR
-   Module: String ;
-   Scope : CARDINAL ;
+   leader,
+   module: String ;
+   scope : CARDINAL ;
 BEGIN
-   Scope := GetScope(Sym) ;
+   scope := GetScope (sym) ;
    IF UseUnderscoreForC
    THEN
-      Module := InitString('_')
+      leader := InitString ('_')
    ELSE
-      Module := InitString('')
+      leader := InitString ('')
    END ;
-   Module := ConCat(GetFullScopePrefix(Module, Scope, Sym),
-                    InitStringCharStar(KeyToCharStar(GetSymName(Sym)))) ;
-   RETURN( StringToKey(Module) )
+   IF IsProcedure (sym) AND IsMonoName (sym)
+   THEN
+      RETURN StringToKey (ConCat (leader, InitStringCharStar (KeyToCharStar (GetSymName (sym)))))
+
+   ELSE
+      RETURN StringToKey (ConCat (GetFullScopePrefix (leader, scope, sym),
+                                  InitStringCharStar (KeyToCharStar (GetSymName (sym)))))
+   END
 END GetFullScopeAsmName ;
 
 
@@ -90,14 +96,19 @@ END GetFullScopeAsmName ;
                     may contain the module name).
 *)
 
-PROCEDURE GetFullSymName (Sym: CARDINAL) : Name ;
+PROCEDURE GetFullSymName (sym: CARDINAL) : Name ;
 VAR
-   Module  : String ;
-   Scope   : CARDINAL ;
+   module: String ;
+   scope : CARDINAL ;
 BEGIN
-   Scope := GetScope(Sym) ;
-   Module := GetModulePrefix(InitString(''), Sym, Scope) ;
-   RETURN( StringToKey(ConCat(Module, InitStringCharStar(KeyToCharStar(GetSymName(Sym))))) )
+   IF IsProcedure (sym) AND IsMonoName (sym)
+   THEN
+      RETURN GetSymName (sym)
+   ELSE
+      scope := GetScope (sym) ;
+      module := GetModulePrefix (InitString (''), sym, scope) ;
+      RETURN StringToKey (ConCat (module, InitStringCharStar (KeyToCharStar (GetSymName (sym)))))
+   END
 END GetFullSymName ;
 
 
diff --git a/gcc/m2/gm2-compiler/M2Base.mod b/gcc/m2/gm2-compiler/M2Base.mod
index 88195f42bf4..bb112166df5 100644
--- a/gcc/m2/gm2-compiler/M2Base.mod
+++ b/gcc/m2/gm2-compiler/M2Base.mod
@@ -2685,8 +2685,8 @@ BEGIN
    *)
 
    C(const       , 'T T T T T T T T T T T T T T T T T T F F T T T T T T T T T T T T T T T T F F F F F F F F F F F F F') ;
-   C(word        , '. T F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F') ;
-   C(byte        , '. . T F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F') ;
+   C(word        , '. T F F F F F F F F F F F F F F F F F F T F F F F F F F F F F F F F F F F F F F F F F F F F F F F') ;
+   C(byte        , '. . T F F F F F F F F F F F F F F F F F T F F F F F F F F F F F F F F F F F F F F F F F F F F F F') ;
    C(address     , '. . . T F F F F F F F T F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F') ;
    C(chr         , '. . . . T F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F') ;
    C(normint     , '. . . . . T F F F F F F F F F F F F F F 2 F F F F F F F F F F F F F F F F F F F F F F F F F F F F') ;
diff --git a/gcc/m2/gm2-compiler/M2Batch.mod b/gcc/m2/gm2-compiler/M2Batch.mod
index b0168a1a921..360ac57ef20 100644
--- a/gcc/m2/gm2-compiler/M2Batch.mod
+++ b/gcc/m2/gm2-compiler/M2Batch.mod
@@ -388,7 +388,8 @@ END ForeachSourceModuleDo ;
 
 
 (*
-   IsSourceSeen - returns TRUE if the source for module, sym, has been seen.
+   IsSourceSeen - returns TRUE if the source for the program module or
+                  implementation module has been seen.
 *)
 
 PROCEDURE IsSourceSeen (sym: CARDINAL) : BOOLEAN ;
diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.def b/gcc/m2/gm2-compiler/M2GCCDeclare.def
index f1568066ad0..5938410ccc6 100644
--- a/gcc/m2/gm2-compiler/M2GCCDeclare.def
+++ b/gcc/m2/gm2-compiler/M2GCCDeclare.def
@@ -40,6 +40,7 @@ EXPORT QUALIFIED FoldConstants,
                  InitDeclarations, StartDeclareScope, EndDeclareScope,
                  DeclareModuleVariables, IsProcedureGccNested,
                  DeclareProcedure, PoisonSymbols, DeclareParameters,
+                 DeclareM2linkGlobals,
                  CompletelyResolved, MarkExported, PrintSym,
                  ConstantKnownAndUsed,
                  PutToBeSolvedByQuads,
@@ -144,6 +145,15 @@ PROCEDURE DeclareProcedure (sym: WORD) ;
 PROCEDURE DeclareModuleVariables (sym: CARDINAL) ;
 
 
+(*
+   DeclareM2linkGlobals - will create M2LINK.StaticInitialization
+                          and M2LINK.ForcedModuleInitOrder providing
+                          they have not already been created.
+*)
+
+PROCEDURE DeclareM2linkGlobals (tokenno: CARDINAL) ;
+
+
 (*
    IsProcedureGccNested - returns TRUE if procedure, sym, will be considered
                           as nested by GCC.
diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
index 81cffb6aae7..7e814b631ee 100644
--- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod
+++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
@@ -32,26 +32,30 @@ IMPLEMENTATION MODULE M2GCCDeclare ;
 
 FROM SYSTEM IMPORT ADDRESS, ADR, WORD ;
 FROM ASCII IMPORT nul ;
+FROM Storage IMPORT ALLOCATE ;
 FROM M2Debug IMPORT Assert ;
 FROM M2Quads IMPORT DisplayQuadRange ;
 
 IMPORT FIO ;
 
 FROM M2Options IMPORT DisplayQuadruples,
-                      GenerateDebugging, GenerateLineDebug, Iso, Optimizing, WholeProgram ;
+                      GenerateDebugging, GenerateLineDebug, Iso, Optimizing, WholeProgram,
+                      ScaffoldStatic, GetRuntimeModuleOverride ;
 
 FROM M2AsmUtil IMPORT GetFullSymName, GetFullScopeAsmName ;
 
+FROM M2Batch IMPORT MakeDefinitionSource ;
 FROM NameKey IMPORT Name, MakeKey, NulName, KeyToCharStar, makekey ;
 FROM M2FileName IMPORT CalculateFileName ;
 FROM DynamicStrings IMPORT String, string, InitString, KillString, InitStringCharStar, Mark ;
 FROM FormatStrings IMPORT Sprintf1 ;
-FROM M2LexBuf IMPORT TokenToLineNo, FindFileNameFromToken, TokenToLocation, UnknownTokenNo ;
+FROM M2LexBuf IMPORT TokenToLineNo, FindFileNameFromToken, TokenToLocation, UnknownTokenNo, BuiltinTokenNo ;
 FROM M2MetaError IMPORT MetaError1, MetaError3 ;
 FROM M2Error IMPORT FlushErrors, InternalError ;
 FROM M2Printf IMPORT printf0, printf1, printf2, printf3 ;
 
 FROM Indexing IMPORT Index, InitIndex, PutIndice, GetIndice, InBounds,
+                     IncludeIndiceIntoIndex, HighIndice,
                      DebugIndex ;
 
 FROM Lists IMPORT List, InitList, IncludeItemIntoList,
@@ -92,7 +96,6 @@ FROM SymbolTable IMPORT NulSym,
                         IsDummy, IsVarAParam, IsProcedureVariable,
                         IsGnuAsm, IsGnuAsmVolatile, IsObject, IsTuple,
                         IsError, IsHiddenType,
-                        IsDefinitionForC, IsHiddenTypeDeclared,
                         IsComponent, IsPublic, IsExtern, IsCtor,
       	       	     	GetMainModule, GetBaseModule, GetModule, GetLocalSym,
                         PutModuleFinallyFunction,
@@ -151,7 +154,9 @@ FROM m2linemap IMPORT location_t, BuiltinsLocation ;
 FROM m2decl IMPORT BuildIntegerConstant, BuildStringConstant, BuildCStringConstant,
                    BuildStartFunctionDeclaration,
                    BuildParameterDeclaration, BuildEndFunctionDeclaration,
-                   DeclareKnownVariable, GetBitsPerBitset ;
+                   DeclareKnownVariable, GetBitsPerBitset, BuildPtrToTypeString,
+                   DeclareM2linkStaticInitialization,
+                   DeclareM2linkForcedModuleInitOrder ;
 
 FROM m2type IMPORT MarkFunctionReferenced, BuildStartRecord, BuildStartVarient, BuildStartFunctionType,
                    BuildStartFieldVarient, BuildStartVarient, BuildStartType, BuildStartArrayType,
@@ -200,6 +205,14 @@ CONST
    Progress  = FALSE ;
    EnableSSA = FALSE ;
 
+TYPE
+   M2LinkEntry = POINTER TO RECORD
+                               var    : CARDINAL ;
+                               gcc    : Tree ;
+                               varname,
+                               modname: Name ;
+                            END ;
+
 VAR
    ToBeSolvedByQuads,               (* constants which must be solved *)
                                     (* by processing the quadruples.  *)
@@ -227,6 +240,7 @@ VAR
    EnumerationIndex    : Index ;
    action              : IsAction ;
    enumDeps            : BOOLEAN ;
+   M2LinkIndex         : Index ;    (* Array of M2LinkEntry.          *)
 
 
 PROCEDURE mystop ; BEGIN END mystop ;
@@ -2730,6 +2744,7 @@ BEGIN
       DeclareTypesConstantsProcedures(scope) ; (* will resolved TYPEs and CONSTs on the ToDo  *)
                                                (* lists.                                      *)
       ForeachModuleDo(DeclareProcedure) ;
+      ForeachModuleDo(DeclareModuleInit) ;
       (*
          now that all types have been resolved it is safe to declare
          variables
@@ -2741,7 +2756,8 @@ BEGIN
       ForeachProcedureDo(scope, DeclareProcedure) ;
       ForeachInnerModuleDo(scope, WalkTypesInModule) ;
       ForeachInnerModuleDo(scope, DeclareTypesConstantsProcedures) ;
-      ForeachInnerModuleDo(scope, StartDeclareScope)
+      ForeachInnerModuleDo(scope, StartDeclareScope) ;
+      DeclareModuleInit(scope)
    ELSE
       DeclareTypesConstantsProcedures(scope) ;
       AssertAllTypesDeclared(scope) ;
@@ -3143,14 +3159,14 @@ END FindOuterModule ;
    DoVariableDeclaration -
 *)
 
-PROCEDURE DoVariableDeclaration (var: CARDINAL; name: ADDRESS;
+PROCEDURE DoVariableDeclaration (var, module: CARDINAL; name: ADDRESS;
                                  isImported, isExported,
                                  isTemporary, isGlobal: BOOLEAN;
                                  scope: Tree) ;
 VAR
-   type    : Tree ;
-   varType : CARDINAL ;
-   location: location_t ;
+   type, initial: Tree ;
+   varType      : CARDINAL ;
+   location     : location_t ;
 BEGIN
    IF IsComponent (var)
    THEN
@@ -3186,15 +3202,93 @@ BEGIN
       type := Mod2Gcc (GetDType (var))
    END ;
    location := TokenToLocation (GetDeclaredMod (var)) ;
+   (* The M2LINK module global variables are a special case and have initializers.  *)
+   initial := DetectM2LinkInitial (location, var, module) ;
    PreAddModGcc (var, DeclareKnownVariable (location,
                                             name, type,
                                             isExported, isImported, isTemporary,
-                                            isGlobal, scope)) ;
+                                            isGlobal, scope, initial)) ;
+   IF initial # NIL
+   THEN
+      (* Remember special case has been created.  *)
+      AddEntryM2Link (var, module, Mod2Gcc (var))
+   END ;
    WatchRemoveList (var, todolist) ;
    WatchIncludeList (var, fullydeclared)
 END DoVariableDeclaration ;
 
 
+(*
+   AddEntryM2Link - remember module_var has been created.
+*)
+
+PROCEDURE AddEntryM2Link (var, module: CARDINAL; gcc: Tree) ;
+VAR
+   entry: M2LinkEntry ;
+BEGIN
+   IF M2LinkIndex = NIL
+   THEN
+      M2LinkIndex := InitIndex (1)
+   END ;
+   NEW (entry) ;
+   entry^.var := var ;
+   entry^.gcc := gcc ;
+   entry^.varname := GetSymName (var) ;
+   entry^.modname := GetSymName (module) ;
+   IncludeIndiceIntoIndex (M2LinkIndex, entry)
+END AddEntryM2Link ;
+
+
+(*
+   GetEntryM2Link - return the gcc tree matching varname modname.
+*)
+
+PROCEDURE GetEntryM2Link (varname, modname: Name) : Tree ;
+VAR
+   entry : M2LinkEntry ;
+   high, i: CARDINAL ;
+BEGIN
+   IF M2LinkIndex # NIL
+   THEN
+      i := 1 ;
+      high := HighIndice (M2LinkIndex) ;
+      WHILE i <= high DO
+         entry := GetIndice (M2LinkIndex, i) ;
+         IF (entry^.varname = varname) AND (entry^.modname = modname)
+         THEN
+            RETURN entry^.gcc
+         END ;
+         INC (i)
+      END
+   END ;
+   RETURN NIL
+END GetEntryM2Link ;
+
+
+(*
+   DeclareM2linkGlobals - will create M2LINK.StaticInitialization
+                          and M2LINK.ForcedModuleInitOrder providing
+                          they have not already been created.
+*)
+
+PROCEDURE DeclareM2linkGlobals (tokenno: CARDINAL) ;
+VAR
+   m2link: Name ;
+BEGIN
+   m2link := MakeKey ('M2LINK') ;
+   IF GetEntryM2Link (MakeKey ('StaticInitialization'), m2link) = NIL
+   THEN
+      Assert (DeclareM2linkStaticInitialization (TokenToLocation (tokenno),
+                                                 VAL (INTEGER, ScaffoldStatic)) # NIL)
+   END ;
+   IF GetEntryM2Link (MakeKey ('ForcedModuleInitOrder'), m2link) = NIL
+   THEN
+      Assert (DeclareM2linkForcedModuleInitOrder (TokenToLocation (tokenno),
+                                                  GetRuntimeModuleOverride ()) # NIL)
+   END ;
+END DeclareM2linkGlobals ;
+
+
 (*
    IsGlobal - is the variable not in a procedure scope.
 *)
@@ -3204,12 +3298,12 @@ VAR
    s: CARDINAL ;
 BEGIN
    s := GetScope(sym) ;
-   WHILE (s#NulSym) AND (NOT IsDefImp(s)) AND (NOT IsModule(s)) DO
-      IF IsProcedure(s)
+   WHILE (s#NulSym) AND (NOT IsDefImp (s)) AND (NOT IsModule (s)) DO
+      IF IsProcedure (s)
       THEN
          RETURN FALSE
       END ;
-      s := GetScope(s)
+      s := GetScope (s)
    END ;
    RETURN TRUE
 END IsGlobal ;
@@ -3230,7 +3324,7 @@ BEGIN
       decl := FindOuterModule (variable) ;
       Assert (AllDependantsFullyDeclared (GetSType (variable))) ;
       PushBinding (ModSym) ;
-      DoVariableDeclaration (variable,
+      DoVariableDeclaration (variable, decl,
                              KeyToCharStar (GetFullSymName (variable)),
                              (* in Modula-2 we are allowed to import from ourselves, but we do not present this to GCC *)
                              IsEffectivelyImported(ModSym, variable) AND (GetMainModule () # decl),
@@ -3243,30 +3337,52 @@ BEGIN
 END DeclareVariable ;
 
 
+(*
+   DetectM2LinkInitial -
+*)
+
+PROCEDURE DetectM2LinkInitial (location: location_t; variable, decl: CARDINAL) : Tree ;
+BEGIN
+   IF (decl # NulSym) AND WholeProgram AND (GetSymName (decl) = MakeKey ('M2LINK'))
+   THEN
+      IF GetSymName (variable) = MakeKey ('StaticInitialization')
+      THEN
+         RETURN BuildIntegerConstant (VAL (INTEGER, ScaffoldStatic))
+      ELSIF GetSymName (variable) = MakeKey ('ForcedModuleInitOrder')
+      THEN
+         RETURN BuildPtrToTypeString (location,
+                                      GetRuntimeModuleOverride (),
+                                      Mod2Gcc (GetSType (variable)))
+      END
+   END ;
+   RETURN NIL
+END DetectM2LinkInitial ;
+
+
 (*
    DeclareVariableWholeProgram - declares a global variable to GCC when using -fm2-whole-program.
 *)
 
-PROCEDURE DeclareVariableWholeProgram (mainModule, var: CARDINAL) ;
+PROCEDURE DeclareVariableWholeProgram (mainModule, variable: CARDINAL) ;
 VAR
    scope: Tree ;
    decl : CARDINAL ;
 BEGIN
-   IF NOT GccKnowsAbout(var)
-   THEN
-      scope := FindContext(mainModule) ;
-      decl := FindOuterModule(var) ;
-      Assert(AllDependantsFullyDeclared(GetSType(var))) ;
-      PushBinding(mainModule) ;
-      DoVariableDeclaration(var,
-                            KeyToCharStar(GetFullSymName(var)),
-                            (NOT IsSourceSeen(decl)) AND
-                            IsEffectivelyImported(mainModule, var) AND (GetMainModule()#decl),
-                            IsExported(mainModule, var),
-                            IsTemporary(var),
-                            IsGlobal(var),
-                            scope) ;
-      PopBinding(mainModule)
+   IF NOT GccKnowsAbout (variable)
+   THEN
+      scope := FindContext (mainModule) ;
+      decl := FindOuterModule (variable) ;
+      Assert (AllDependantsFullyDeclared (GetSType (variable))) ;
+      PushBinding (mainModule) ;
+      DoVariableDeclaration (variable, decl,
+                             KeyToCharStar (GetFullSymName (variable)),
+                             (NOT IsSourceSeen (decl)) AND
+                             IsEffectivelyImported (mainModule, variable) AND (GetMainModule () # decl),
+                             IsExported (mainModule, variable),
+                             IsTemporary (variable),
+                             IsGlobal (variable),
+                             scope) ;
+      PopBinding (mainModule)
    END
 END DeclareVariableWholeProgram ;
 
@@ -3327,22 +3443,22 @@ END DeclareImportedVariables ;
 
 
 (*
-   DeclareImportedVariablesWholeProgram - declares all imported variables to GM2.
+   DeclareImportedVariablesWholeProgram - declares all imported variables.
 *)
 
 PROCEDURE DeclareImportedVariablesWholeProgram (sym: WORD) ;
 BEGIN
-   IF IsVar(sym)
+   IF IsVar (sym)
    THEN
-      IF NOT IsSourceSeen(FindOuterModule(sym))
+      IF NOT IsSourceSeen (FindOuterModule (sym))
       THEN
          (* import is necessary, even for -fm2-whole-program as we
             cannot see the source.  *)
-         DeclareVariableWholeProgram(GetMainModule(), sym)
+         DeclareVariableWholeProgram (GetMainModule (), sym)
       END
-   ELSIF IsDefImp(sym)
+   ELSIF IsDefImp (sym)
    THEN
-      ForeachExportedDo(sym, DeclareImportedVariablesWholeProgram)
+      ForeachExportedDo (sym, DeclareImportedVariablesWholeProgram)
    END
 END DeclareImportedVariablesWholeProgram ;
 
@@ -3354,7 +3470,7 @@ END DeclareImportedVariablesWholeProgram ;
 PROCEDURE DeclareLocalVariable (var: CARDINAL) ;
 BEGIN
    Assert (AllDependantsFullyDeclared (var)) ;
-   DoVariableDeclaration (var,
+   DoVariableDeclaration (var, NulSym,
                           KeyToCharStar (GetFullSymName (var)),
                           FALSE,  (* local variables cannot be imported *)
                           FALSE,  (* or exported *)
@@ -3398,7 +3514,7 @@ BEGIN
    Var := GetNth (sym, i) ;
    WHILE Var # NulSym DO
       Assert (AllDependantsFullyDeclared (GetSType (Var))) ;
-      DoVariableDeclaration (Var,
+      DoVariableDeclaration (Var, NulSym,
                              KeyToCharStar (GetFullSymName (Var)),
                              FALSE,   (* inner module variables cannot be imported *)
                              FALSE,   (* or exported (as far as GCC is concerned)  *)
@@ -6170,6 +6286,16 @@ BEGIN
 END ConstantKnownAndUsed ;
 
 
+(*
+   InitM2LinkModule -
+*)
+
+PROCEDURE InitM2LinkModule ;
+BEGIN
+   M2LinkIndex := NIL
+END InitM2LinkModule ;
+
+
 (*
    InitDeclarations - initializes default types and the source filename.
 *)
@@ -6195,5 +6321,6 @@ BEGIN
    EnumerationIndex := InitIndex(1) ;
    IncludeElementIntoSet(WatchList, 8) ;
    HaveInitDefaultTypes := FALSE ;
-   recursionCaught := FALSE
+   recursionCaught := FALSE ;
+   InitM2LinkModule
 END M2GCCDeclare.
diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod
index ebe64a170fb..89c035897d3 100644
--- a/gcc/m2/gm2-compiler/M2GenGCC.mod
+++ b/gcc/m2/gm2-compiler/M2GenGCC.mod
@@ -91,7 +91,7 @@ FROM M2MetaError IMPORT MetaErrorT0, MetaErrorT1, MetaErrorT2, MetaErrorT3,
 FROM M2Options IMPORT DisplayQuadruples, UnboundedByReference, PedanticCast,
                       VerboseUnbounded, Iso, Pim, DebugBuiltins, WholeProgram,
                       StrictTypeChecking, AutoInit, cflag, ScaffoldMain,
-                      ScaffoldDynamic, ScaffoldStatic, GetRuntimeModuleOverride,
+                      ScaffoldDynamic, ScaffoldStatic,
                       DebugTraceQuad, DebugTraceAPI ;
 
 FROM M2Printf IMPORT printf0, printf1, printf2, printf4 ;
@@ -149,7 +149,8 @@ FROM M2GCCDeclare IMPORT WalkAction,
                          CompletelyResolved,
                          PoisonSymbols, GetTypeMin, GetTypeMax,
                          IsProcedureGccNested, DeclareParameters,
-                         ConstantKnownAndUsed, PrintSym ;
+                         ConstantKnownAndUsed, PrintSym,
+                         DeclareM2linkGlobals ;
 
 FROM M2Range IMPORT CodeRangeCheck, FoldRangeCheck, CodeErrorCheck, GetMinMax ;
 
@@ -206,7 +207,7 @@ FROM m2tree IMPORT Tree, debug_tree ;
 FROM m2linemap IMPORT location_t ;
 
 FROM m2decl IMPORT BuildStringConstant, DeclareKnownConstant, GetBitsPerBitset,
-                   BuildIntegerConstant, DeclareM2linkGlobals,
+                   BuildIntegerConstant,
                    BuildModuleCtor, DeclareModuleCtor ;
 
 FROM m2statement IMPORT BuildAsm, BuildProcedureCallTree, BuildParam, BuildFunctValue,
@@ -1146,6 +1147,7 @@ PROCEDURE CodeFinallyEnd (moduleSym: CARDINAL;
                           CompilingMainModule: BOOLEAN) ;
 VAR
    location  : location_t;
+   tokenpos  : CARDINAL ;
    ctor, init,
    fini, dep : CARDINAL ;
 BEGIN
@@ -1156,7 +1158,8 @@ BEGIN
          EmitLineNote(string(FileName), op1) ;
       *)
 
-      location := TokenToLocation (GetDeclaredMod (moduleSym)) ;
+      tokenpos := GetDeclaredMod (moduleSym) ;
+      location := TokenToLocation (tokenpos) ;
       GetModuleCtors (moduleSym, ctor, init, fini, dep) ;
       finishFunctionDecl (location, Mod2Gcc (fini)) ;
       BuildEndFunctionCode (location, Mod2Gcc (fini),
@@ -1168,7 +1171,7 @@ BEGIN
             (moduleSym = GetMainModule ())
          THEN
             qprintf0 ("        generating scaffold m2link information\n");
-            DeclareM2linkGlobals (location, VAL (INTEGER, ScaffoldStatic), GetRuntimeModuleOverride ())
+            DeclareM2linkGlobals (tokenpos)
          END
       END
    END
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index 72a350d4d35..8b09b00a10d 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -116,7 +116,7 @@ FROM SymbolTable IMPORT ModeOfAddr, GetMode, PutMode, GetSymName, IsUnknown,
                         IsImportStatement, IsImport, GetImportModule, GetImportDeclared,
                         GetImportStatementList,
                         GetModuleDefImportStatementList, GetModuleModImportStatementList,
-                        IsCtor, IsPublic, IsExtern,
+                        IsCtor, IsPublic, IsExtern, IsMonoName,
 
                         GetUnboundedRecordType,
                         GetUnboundedAddressOffset,
@@ -205,7 +205,8 @@ FROM M2Options IMPORT NilChecking,
                       Pedantic, CompilerDebugging, GenerateDebugging,
                       GenerateLineDebug, Exceptions,
                       Profiling, Coding, Optimizing,
-                      ScaffoldDynamic, ScaffoldStatic, cflag, ScaffoldMain, SharedFlag ;
+                      ScaffoldDynamic, ScaffoldStatic, cflag,
+                      ScaffoldMain, SharedFlag, WholeProgram ;
 
 FROM M2Pass IMPORT IsPassCodeGeneration, IsNoPass ;
 
@@ -257,7 +258,7 @@ IMPORT M2Error ;
 CONST
    DebugStackOn = TRUE ;
    DebugVarients = FALSE ;
-   BreakAtQuad = 391 ;
+   BreakAtQuad = 4423 ;
    DebugTokPos = FALSE ;
 
 TYPE
@@ -2412,6 +2413,47 @@ BEGIN
 END BuildM2LinkFunction ;
 
 
+(*
+   BuildTry - build the try statement for main.
+*)
+
+PROCEDURE BuildTry (tokno: CARDINAL) ;
+BEGIN
+   IF Exceptions
+   THEN
+      PushWord (TryStack, NextQuad) ;
+      PushWord (CatchStack, 0) ;
+      GenQuadO (tokno, TryOp, NulSym, NulSym, 0, FALSE)
+   END
+END BuildTry ;
+
+
+(*
+   BuildExcept - build the except block for main.
+*)
+
+PROCEDURE BuildExcept (tokno: CARDINAL) ;
+VAR
+   catchProcedure: CARDINAL ;
+BEGIN
+   IF Exceptions
+   THEN
+      BuildExceptInitial (tokno) ;
+      catchProcedure := GetQualidentImport (tokno,
+                                            MakeKey ('DefaultErrorCatch'),
+                                            MakeKey ('RTExceptions')) ;
+      IF catchProcedure # NulSym
+      THEN
+         PushTtok (catchProcedure, tokno) ;
+         PushT (0) ;
+         BuildProcedureCall (tokno)
+      END ;
+      BuildRTExceptLeave (tokno, TRUE) ;
+      GenQuadO (tokno, CatchEndOp, NulSym, NulSym, NulSym, FALSE)
+   END
+END BuildExcept ;
+
+
 (*
    BuildM2MainFunction - creates the main function with appropriate calls to the scaffold.
 *)
@@ -2425,16 +2467,21 @@ BEGIN
          int
          main (int argc, char *argv[], char *envp[])
          {
-            _M2_init (argc, argv, envp);
-            _M2_fini (argc, argv, envp);
-            return 0;
+            try {
+               _M2_init (argc, argv, envp);
+               _M2_fini (argc, argv, envp);
+               return 0;
+            }
+            catch (...) {
+               RTExceptions_DefaultErrorCatch ();
+            }
          }
       *)
       PushT (mainFunction) ;
       BuildProcedureStart ;
       BuildProcedureBegin ;
       StartScope (mainFunction) ;
-
+      BuildTry (tokno) ;
       (* _M2_init (argc, argv, envp);  *)
       PushTtok (initFunction, tokno) ;
       PushTtok (RequestSym (tokno, MakeKey ("argc")), tokno) ;
@@ -2453,6 +2500,7 @@ BEGIN
 
       PushZero (tokno, Integer) ;
       BuildReturn (tokno) ;
+      BuildExcept (tokno) ;
       EndScope ;
       BuildProcedureEnd ;
       PopN (1)
@@ -2656,6 +2704,13 @@ BEGIN
       (* Each module needs a ctor to register the module
          init/finish/dep with M2RTS.  *)
       BuildM2CtorFunction (tok, moduleSym)
+   ELSIF WholeProgram
+   THEN
+      DeclareScaffold (tok) ;
+      BuildM2DepFunction (tok, moduleSym) ;  (* Per module dependency.  *)
+      (* Each module needs a ctor to register the module
+         init/finish/dep with M2RTS.  *)
+      BuildM2CtorFunction (tok, moduleSym)
    END
 END BuildScaffold ;
 
@@ -13046,6 +13101,10 @@ BEGIN
    IF IsExtern (proc)
    THEN
       printf0 (" (extern)")
+   END ;
+   IF IsMonoName (proc)
+   THEN
+      printf0 (" (mononame)")
    END
 END DisplayProcedureAttributes ;
 
diff --git a/gcc/m2/gm2-compiler/M2Scaffold.mod b/gcc/m2/gm2-compiler/M2Scaffold.mod
index dc228184d80..ea8cddf9e2c 100644
--- a/gcc/m2/gm2-compiler/M2Scaffold.mod
+++ b/gcc/m2/gm2-compiler/M2Scaffold.mod
@@ -27,6 +27,7 @@ FROM SymbolTable IMPORT NulSym, MakeProcedure, PutFunction,
                         MakeSubrange, PutSubrange,
                         MakeSubscript, PutSubscript, PutArraySubscript,
                         MakeVar, PutVar, MakeProcedureCtorExtern,
+                        PutMonoName,
                         GetMainModule, GetModuleCtors, MakeDefImp,
                         PutModuleCtorExtern, IsDefinitionForC,
                         ForeachModuleDo, IsDefImp, IsModule,
@@ -49,7 +50,7 @@ FROM FIO IMPORT File, EOF, IsNoError, Close ;
 
 FROM M2Options IMPORT GetUselist, ScaffoldStatic, ScaffoldDynamic, GenModuleList,
                       GetGenModuleFilename, GetUselistFilename, GetUselist, cflag,
-                      SharedFlag ;
+                      SharedFlag, WholeProgram ;
 
 FROM M2Base IMPORT Proc ;
 
@@ -76,6 +77,7 @@ VAR
    ctorModules,
    ctorGlobals   : List ;
    ctorArrayType : CARDINAL ;
+   initialized   : BOOLEAN ;
 
 
 (* The dynamic scaffold takes the form:
@@ -251,14 +253,14 @@ BEGIN
    END ;
    IF sym # GetMainModule ()
    THEN
-      PutModuleCtorExtern (tok, sym)
+      PutModuleCtorExtern (tok, sym, NOT WholeProgram)
    END ;
    RETURN sym
 END LookupModuleSym ;
 
 
 (*
-   addDependentStatement - 
+   addDependentStatement -
 *)
 
 PROCEDURE addDependentStatement (graph: Graph; moduleSym: CARDINAL; list: List) ;
@@ -393,7 +395,7 @@ BEGIN
    THEN
       IF (moduleSym # GetMainModule ()) AND (NOT IsModuleBuiltin (moduleSym))
       THEN
-         PutModuleCtorExtern (ctorTok, moduleSym) ;
+         PutModuleCtorExtern (ctorTok, moduleSym, NOT WholeProgram) ;
          IncludeItemIntoList (uselistModules, moduleSym)
       END
    END
@@ -513,12 +515,13 @@ END CreateCtorList ;
 
 PROCEDURE DeclareModuleExtern (tokenno: CARDINAL) ;
 VAR
+   n1    : Name ;
    init,
    fini,
    dep,
    ctor,
    module: CARDINAL ;
-   n, i : CARDINAL ;
+   n, i  : CARDINAL ;
 BEGIN
    InitList (ctorModules) ;
    i := 1 ;
@@ -527,10 +530,15 @@ BEGIN
       module := GetItemFromList (uselistModules, i) ;
       IF module # GetMainModule ()
       THEN
-         PutModuleCtorExtern (tokenno, module)
+         PutModuleCtorExtern (tokenno, module, NOT WholeProgram)
       END ;
       GetModuleCtors (module, ctor, init, fini, dep) ;
       IncludeItemIntoList (ctorModules, ctor) ;
+      IF Debugging
+      THEN
+         n1 := GetSymName (module) ;
+         printf1 ("%a_ctor added to ctorModules\n", n1)
+      END ;
       INC (i)
    END
 END DeclareModuleExtern ;
@@ -548,7 +556,8 @@ BEGIN
    THEN
       DeclareCtorGlobal (tokenno) ;
       DeclareModuleExtern (tokenno) ;
-      linkFunction := MakeProcedure (tokenno, MakeKey ("_M2_link"))
+      linkFunction := MakeProcedure (tokenno, MakeKey ("_M2_link")) ;
+      PutMonoName (linkFunction, TRUE)
    ELSIF ScaffoldDynamic AND (NOT cflag)
    THEN
       MetaErrorT0 (tokenno,
@@ -556,7 +565,9 @@ BEGIN
    END ;
 
    initFunction := MakeProcedure (tokenno, MakeKey ("_M2_init")) ;
+   PutMonoName (initFunction, TRUE) ;
    finiFunction := MakeProcedure (tokenno, MakeKey ("_M2_fini")) ;
+   PutMonoName (finiFunction, TRUE) ;
    IF SharedFlag
    THEN
       PutCtor (initFunction, TRUE) ;
@@ -566,6 +577,7 @@ BEGIN
       DeclareArgEnvParams (tokenno, finiFunction) ;
 
       mainFunction := MakeProcedure (tokenno, MakeKey ("main")) ;
+      PutMonoName (mainFunction, TRUE) ;
       StartScope (mainFunction) ;
       PutFunction (mainFunction, Integer) ;
       DeclareArgEnvParams (tokenno, mainFunction) ;
@@ -596,11 +608,16 @@ END DeclareArgEnvParams ;
 
 PROCEDURE DeclareScaffold (tokno: CARDINAL) ;
 BEGIN
-   DeclareScaffoldFunctions (tokno)
+   IF NOT initialized
+   THEN
+      initialized := TRUE ;
+      DeclareScaffoldFunctions (tokno)
+   END
 END DeclareScaffold ;
 
 
 BEGIN
+   initialized := FALSE ;
    finiFunction := NulSym ;
    initFunction := NulSym ;
    mainFunction := NulSym ;
diff --git a/gcc/m2/gm2-compiler/P1SymBuild.mod b/gcc/m2/gm2-compiler/P1SymBuild.mod
index a659c1fc8bd..06756bcf5d1 100644
--- a/gcc/m2/gm2-compiler/P1SymBuild.mod
+++ b/gcc/m2/gm2-compiler/P1SymBuild.mod
@@ -606,12 +606,7 @@ BEGIN
    IF CompilingDefinitionModule() AND DoesNotNeedExportList(GetCurrentModule())
    THEN
       (* printf1('exporting identifier %a\n', OperandT(1)) ; *)
-      IF IsDefinitionForC(GetCurrentModule())
-      THEN
-         PutExportUnQualified (OperandTok (1), OperandT(1))
-      ELSE
-         PutExportQualified (OperandTok (1), OperandT(1))
-      END
+      PutExportQualified (OperandTok (1), OperandT(1))
    END
 END CheckExplicitExported ;
 
diff --git a/gcc/m2/gm2-compiler/P2Build.bnf b/gcc/m2/gm2-compiler/P2Build.bnf
index 35925947234..590047eecbe 100644
--- a/gcc/m2/gm2-compiler/P2Build.bnf
+++ b/gcc/m2/gm2-compiler/P2Build.bnf
@@ -188,7 +188,7 @@ VAR
    tok  : CARDINAL ;
 BEGIN
    PopTtok (ident, tok) ;
-   IF ident # MakeKey ('noreturn')
+   IF ident # MakeKey ('unused')
    THEN
       MetaErrorT1 (tok, 'attribute {%1k} is not allowed in the parameter formal type section, only unused is allowed', ident)
    END
diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def
index 12270ed0289..2983ec46fde 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.def
+++ b/gcc/m2/gm2-compiler/SymbolTable.def
@@ -200,6 +200,7 @@ EXPORT QUALIFIED NulSym,
                  PutUnused, IsUnused,
                  PutVariableSSA, IsVariableSSA,
                  PutPublic, IsPublic, PutCtor, IsCtor, PutExtern, IsExtern,
+                 PutMonoName, IsMonoName,
 
                  IsDefImp,
                  IsModule,
@@ -587,6 +588,20 @@ PROCEDURE MakeProcedure (tok: CARDINAL; ProcedureName: Name) : CARDINAL ;
 PROCEDURE MakeProcedureCtorExtern (tokenno: CARDINAL; modulename: Name) : CARDINAL ;
 
 
+(*
+   PutMonoName - changes the IsMonoName boolean inside the procedure.
+*)
+
+PROCEDURE PutMonoName (sym: CARDINAL; value: BOOLEAN) ;
+
+
+(*
+   IsMonoName - returns the public boolean associated with a procedure.
+*)
+
+PROCEDURE IsMonoName (sym: CARDINAL) : BOOLEAN ;
+
+
 (*
    PutExtern - changes the extern boolean inside the procedure.
 *)
@@ -654,7 +669,7 @@ PROCEDURE MakeModuleCtor (moduleTok, beginTok, finallyTok: CARDINAL;
                          procedures.
 *)
 
-PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL) ;
+PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL; external: BOOLEAN) ;
 
 
 (*
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod
index 75522c4a57e..41e9c8a2d99 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -364,6 +364,7 @@ TYPE
                IsExtern      : BOOLEAN ;    (* Make this procedure extern.   *)
                IsPublic      : BOOLEAN ;    (* Make this procedure visible.  *)
                IsCtor        : BOOLEAN ;    (* Is this procedure a ctor?     *)
+               IsMonoName    : BOOLEAN ;    (* Ignores module name prefix.   *)
                Unresolved    : SymbolTree ; (* All symbols currently         *)
                                             (* unresolved in this procedure. *)
                ScopeQuad     : CARDINAL ;   (* Index into quads for scope    *)
@@ -3103,11 +3104,14 @@ BEGIN
    THEN
       (* The ctor procedure must be public.  *)
       ctor.ctor := MakeProcedure (moduleTok, GenName ("_M2_", name, "_ctor")) ;
-      PutCtor (ctor.ctor, pub) ;
+      PutCtor (ctor.ctor, TRUE) ;
+      Assert (pub) ;
       PutPublic (ctor.ctor, pub) ;
       PutExtern (ctor.ctor, NOT pub) ;
+      PutMonoName (ctor.ctor, TRUE) ;
       (* The dep procedure is local to the module.  *)
       ctor.dep := MakeProcedure (moduleTok, GenName ("_M2_", name, "_dep")) ;
+      PutMonoName (ctor.dep, TRUE)
    ELSE
       ctor.ctor := NulSym ;
       ctor.dep := NulSym
@@ -3116,10 +3120,12 @@ BEGIN
    ctor.init := MakeProcedure (beginTok, GenName ("_M2_", name, "_init")) ;
    PutPublic (ctor.init, pub) ;
    PutExtern (ctor.init, NOT pub) ;
+   PutMonoName (ctor.init, NOT inner) ;
    DeclareArgEnvParams (beginTok, ctor.init) ;
    ctor.fini := MakeProcedure (finallyTok, GenName ("_M2_", name, "_fini")) ;
    PutPublic (ctor.fini, pub) ;
    PutExtern (ctor.fini, NOT pub) ;
+   PutMonoName (ctor.fini, NOT inner) ;
    DeclareArgEnvParams (beginTok, ctor.fini)
 END InitCtorFields ;
 
@@ -3667,27 +3673,31 @@ BEGIN
    (* If the ctor does not exist then make it extern/ (~extern) public.  *)
    IF ctor.ctor = NulSym
    THEN
-      ctor.ctor := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_ctor"))
+      ctor.ctor := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_ctor")) ;
+      PutMonoName (ctor.ctor, TRUE)
    END ;
    PutProcedureExternPublic (ctor.ctor, extern, NOT extern) ;
-   PutCtor (ctor.ctor, NOT extern) ;
+   PutCtor (ctor.ctor, TRUE) ;
    (* If the ctor does not exist then make it extern/ (~extern) public.  *)
    IF ctor.dep = NulSym
    THEN
-      ctor.dep := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_dep"))
+      ctor.dep := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_dep")) ;
+      PutMonoName (ctor.dep, TRUE)
    END ;
    PutProcedureExternPublic (ctor.dep, extern, NOT extern) ;
    (* If init/fini do not exist then create them.  *)
    IF ctor.init = NulSym
    THEN
       ctor.init := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_init")) ;
-      DeclareArgEnvParams (tok, ctor.init)
+      DeclareArgEnvParams (tok, ctor.init) ;
+      PutMonoName (ctor.init, NOT IsInnerModule (sym))
    END ;
    PutProcedureExternPublic (ctor.init, extern, NOT extern) ;
    IF ctor.fini = NulSym
    THEN
       ctor.fini := MakeProcedure (tok, GenName ("_M2_", GetSymName (sym), "_fini")) ;
-      DeclareArgEnvParams (tok, ctor.fini)
+      DeclareArgEnvParams (tok, ctor.fini) ;
+      PutMonoName (ctor.fini, NOT IsInnerModule (sym))
    END ;
    PutProcedureExternPublic (ctor.fini, extern, NOT extern)
 END PutCtorExtern ;
@@ -3700,7 +3710,7 @@ END PutCtorExtern ;
                          procedures.
 *)
 
-PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL) ;
+PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL; external: BOOLEAN) ;
 VAR
    pSym: PtrToSymbol ;
 BEGIN
@@ -3709,8 +3719,8 @@ BEGIN
    WITH pSym^ DO
       CASE SymbolType OF
 
-      DefImpSym:  PutCtorExtern (tok, sym, DefImp.ctors, TRUE) |
-      ModuleSym:  PutCtorExtern (tok, sym, Module.ctors, TRUE)
+      DefImpSym:  PutCtorExtern (tok, sym, DefImp.ctors, external) |
+      ModuleSym:  PutCtorExtern (tok, sym, Module.ctors, external)
 
       ELSE
          InternalError ('expecting DefImp or Module symbol')
@@ -3765,6 +3775,7 @@ BEGIN
             IsExtern := FALSE ;          (* Make this procedure external. *)
             IsPublic := FALSE ;          (* Make this procedure visible.  *)
             IsCtor := FALSE ;            (* Is this procedure a ctor?     *)
+            IsMonoName := FALSE ;        (* Overrides module name prefix. *)
             Scope := GetCurrentScope() ; (* Scope of procedure.           *)
             InitTree(Unresolved) ;       (* All symbols currently         *)
                                          (* unresolved in this procedure. *)
@@ -3809,6 +3820,48 @@ BEGIN
 END MakeProcedure ;
 
 
+(*
+   PutMonoName - changes the IsMonoName boolean inside the procedure.
+*)
+
+PROCEDURE PutMonoName (sym: CARDINAL; value: BOOLEAN) ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   pSym := GetPsym (sym) ;
+   WITH pSym^ DO
+      CASE SymbolType OF
+
+      ProcedureSym: Procedure.IsMonoName := value
+
+      ELSE
+         InternalError ('expecting ProcedureSym symbol')
+      END
+   END
+END PutMonoName ;
+
+
+(*
+   IsMonoName - returns the public boolean associated with a procedure.
+*)
+
+PROCEDURE IsMonoName (sym: CARDINAL) : BOOLEAN ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   pSym := GetPsym (sym) ;
+   WITH pSym^ DO
+      CASE SymbolType OF
+
+      ProcedureSym:  RETURN Procedure.IsMonoName
+
+      ELSE
+         InternalError ('expecting ProcedureSym symbol')
+      END
+   END
+END IsMonoName ;
+
+
 (*
    PutExtern - changes the extern boolean inside the procedure.
 *)
@@ -8488,8 +8541,6 @@ END GetFromOuterModule ;
 (*
    IsExportUnQualified - returns true if a symbol, Sym, was defined as
                          being EXPORT UNQUALIFIED.
-                         Sym is expected to be either a procedure or a
-                         variable.
 *)
 
 PROCEDURE IsExportUnQualified (Sym: CARDINAL) : BOOLEAN ;
@@ -8497,7 +8548,6 @@ VAR
    pSym       : PtrToSymbol ;
    OuterModule: CARDINAL ;
 BEGIN
-   Assert(IsVar(Sym) OR IsProcedure(Sym)) ;
    OuterModule := Sym ;
    REPEAT
       OuterModule := GetScope(OuterModule)
diff --git a/gcc/m2/gm2-gcc/init.cc b/gcc/m2/gm2-gcc/init.cc
index 3453a477412..8fa074e2894 100644
--- a/gcc/m2/gm2-gcc/init.cc
+++ b/gcc/m2/gm2-gcc/init.cc
@@ -105,12 +105,9 @@ EXTERN void exit (int);
 EXTERN void M2Comp_compile (const char *filename);
 EXTERN void RTExceptions_DefaultErrorCatch (void);
 
-int StaticInitialization = 1;
-char *ForcedModuleInitOrder = NULL;
 
-
-/* FrontEndInit - initialise the modules, this is a global
-   initialisation.  This is called once.  */
+/* FrontEndInit initialize the modules.  This is a global
+   initialization and it is called once.  */
 
 void
 init_FrontEndInit (void)
@@ -148,8 +145,8 @@ init_FrontEndInit (void)
   _M2_M2Options_init (0, NULL, NULL);
 }
 
-/* PerCompilationInit - initialise the modules before compiling,
-   filename.  This is to be called every time we compile a new file.  */
+/* PerCompilationInit initialize the modules before compiling,
+   filename.  This is called every time we compile a new file.  */
 
 void
 init_PerCompilationInit (const char *filename)
diff --git a/gcc/m2/gm2-gcc/m2decl.cc b/gcc/m2/gm2-gcc/m2decl.cc
index 5fd391ea877..62bfefd2530 100644
--- a/gcc/m2/gm2-gcc/m2decl.cc
+++ b/gcc/m2/gm2-gcc/m2decl.cc
@@ -41,35 +41,35 @@ static GTY (()) tree param_type_list;
 static GTY (()) tree param_list = NULL_TREE; /* Ready for the next time we
                                                 call/define a function.  */
 
-/* DeclareM2linkGlobals creates the following code in the application
-   module globals:
+tree
+m2decl_DeclareM2linkStaticInitialization (location_t location,
+					  int ScaffoldStatic)
+{
+  m2block_pushGlobalScope ();
+  /* Generate: int M2LINK_StaticInitialization = ScaffoldStatic;  */
+  tree init = m2decl_BuildIntegerConstant (ScaffoldStatic);
+  tree static_init = m2decl_DeclareKnownVariable (location, "M2LINK_StaticInitialization",
+						  integer_type_node,
+						  TRUE, FALSE, FALSE, TRUE, NULL_TREE, init);
+  m2block_popGlobalScope ();
+  return static_init;
+}
 
-   int StaticInitialization = ScaffoldStatic;
-   const char *ForcedModuleInitOrder = RuntimeOverride;  */
 
-void
-m2decl_DeclareM2linkGlobals (location_t location,
-			     int ScaffoldStatic, const char *RuntimeOverride)
+tree
+m2decl_DeclareM2linkForcedModuleInitOrder (location_t location,
+					   const char *RuntimeOverride)
 {
   m2block_pushGlobalScope ();
-  /* Generate: int StaticInitialization = ScaffoldStatic;  */
-  tree static_init = m2decl_DeclareKnownVariable (location, "StaticInitialization",
-						  integer_type_node,
-						  TRUE, FALSE, FALSE, TRUE, NULL_TREE);
-  DECL_INITIAL (static_init) = m2decl_BuildIntegerConstant (ScaffoldStatic);
   /* Generate: const char *ForcedModuleInitOrder = RuntimeOverride;  */
   tree ptr_to_char = build_pointer_type (char_type_node);
   TYPE_READONLY (ptr_to_char) = TRUE;
-  tree forced_order = m2decl_DeclareKnownVariable (location, "ForcedModuleInitOrder",
+  tree init = m2decl_BuildPtrToTypeString (location, RuntimeOverride, ptr_to_char);
+  tree forced_order = m2decl_DeclareKnownVariable (location, "M2LINK_ForcedModuleInitOrder",
 						   ptr_to_char,
-						   TRUE, FALSE, FALSE, TRUE, NULL_TREE);
-  if (RuntimeOverride == NULL || (strlen (RuntimeOverride) == 0))
-    DECL_INITIAL (forced_order) = m2convert_BuildConvert (location, ptr_to_char,
-							  m2decl_BuildIntegerConstant (0),
-							  FALSE);
-  else
-    DECL_INITIAL (forced_order) = build_string_literal (strlen (RuntimeOverride), RuntimeOverride);
+						   TRUE, FALSE, FALSE, TRUE, NULL_TREE, init);
   m2block_popGlobalScope ();
+  return forced_order;
 }
 
 
@@ -78,7 +78,7 @@ m2decl_DeclareM2linkGlobals (location_t location,
 tree
 m2decl_DeclareKnownVariable (location_t location, const char *name, tree type,
                              int exported, int imported, int istemporary,
-                             int isglobal, tree scope)
+                             int isglobal, tree scope, tree initial)
 {
   tree id;
   tree decl;
@@ -112,6 +112,9 @@ m2decl_DeclareKnownVariable (location_t location, const char *name, tree type,
 
   DECL_CONTEXT (decl) = scope;
 
+  if (initial)
+    DECL_INITIAL (decl) = initial;
+
   m2block_pushDecl (decl);
 
   if (DECL_SIZE (decl) == 0)
@@ -361,6 +364,18 @@ m2decl_BuildStringConstant (const char *string, int length)
   // maybe_wrap_with_location
 }
 
+
+tree
+m2decl_BuildPtrToTypeString (location_t location, const char *string, tree type)
+{
+  if ((string == NULL) || (strlen (string) == 0))
+    return m2convert_BuildConvert (location, type,
+				   m2decl_BuildIntegerConstant (0),
+				   FALSE);
+  return build_string_literal (strlen (string), string);
+}
+
+
 /* BuildIntegerConstant - return a tree containing the integer value.  */
 
 tree
diff --git a/gcc/m2/gm2-gcc/m2decl.def b/gcc/m2/gm2-gcc/m2decl.def
index 1d257a89b71..0f924dd1309 100644
--- a/gcc/m2/gm2-gcc/m2decl.def
+++ b/gcc/m2/gm2-gcc/m2decl.def
@@ -41,17 +41,19 @@ PROCEDURE BuildModuleCtor (moduleCtor: Tree) ;
 PROCEDURE DeclareModuleCtor (decl: Tree) : Tree ;
 
 
+
 (*
-   DeclareM2linkGlobals creates the following code in the application
-   module globals:
 
-   int StaticInitialization = ScaffoldStatic;
-   const char *ForcedModuleInitOrder = RuntimeOverride;
 *)
 
-PROCEDURE DeclareM2linkGlobals (location: location_t;
-                                ScaffoldStatic: INTEGER;
-                                RuntimeOverride: ADDRESS) ;
+PROCEDURE DeclareM2linkForcedModuleInitOrder (location: location_t;
+                                              RuntimeOverride: ADDRESS) : Tree ;
+
+
+PROCEDURE DeclareM2linkStaticInitialization (location: location_t;
+                                             ScaffoldStatic: INTEGER) : Tree ;
+
+PROCEDURE BuildPtrToTypeString (location: location_t; string: ADDRESS; type: Tree) : Tree ;
 
 
 (*
@@ -105,7 +107,7 @@ PROCEDURE BuildStringConstantType (length: INTEGER; string: ADDRESS; type: Tree)
 
 PROCEDURE DeclareKnownVariable (location: location_t; name: ADDRESS; type: Tree;
                                 exported, imported, istemporary, isglobal: BOOLEAN;
-                                scope: Tree) : Tree ;
+                                scope, initial: Tree) : Tree ;
 
 
 (*
diff --git a/gcc/m2/gm2-gcc/m2decl.h b/gcc/m2/gm2-gcc/m2decl.h
index 87a96a94fb7..187569484a4 100644
--- a/gcc/m2/gm2-gcc/m2decl.h
+++ b/gcc/m2/gm2-gcc/m2decl.h
@@ -36,8 +36,12 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 #endif /* !__GNUG__.  */
 #endif /* !m2decl_c.  */
 
-EXTERN void m2decl_DeclareM2linkGlobals (location_t location,
-					 int ScaffoldStatic, const char *RuntimeOverride);
+
+EXTERN tree m2decl_DeclareM2linkStaticInitialization (location_t location,
+						      int ScaffoldStatic);
+EXTERN tree m2decl_DeclareM2linkForcedModuleInitOrder (location_t location,
+						       const char *RuntimeOverride);
+EXTERN tree m2decl_BuildPtrToTypeString (location_t location, const char *string, tree type);
 EXTERN void m2decl_BuildModuleCtor (tree module_ctor);
 EXTERN tree m2decl_DeclareModuleCtor (tree decl);
 EXTERN tree m2decl_GetDeclContext (tree t);
@@ -63,7 +67,7 @@ EXTERN tree m2decl_DeclareKnownConstant (location_t location, tree type,
 EXTERN tree m2decl_DeclareKnownVariable (location_t location, const char *name,
                                          tree type, int exported, int imported,
                                          int istemporary, int isglobal,
-                                         tree scope);
+                                         tree scope, tree initial);
 
 EXTERN tree m2decl_BuildStringConstantType (int length, const char *string,
                                             tree type);
diff --git a/gcc/m2/tools-src/boilerplate.py b/gcc/m2/tools-src/boilerplate.py
index 0976aab2671..f0b266f403f 100644
--- a/gcc/m2/tools-src/boilerplate.py
+++ b/gcc/m2/tools-src/boilerplate.py
@@ -32,16 +32,16 @@ error_count = 0
 seen_files = []
 output_name = None
 
-ISO_COPYRIGHT = "Copyright ISO/IEC"
-COPYRIGHT = "Copyright (C)"
-GNU_PUBLIC_LICENSE = "GNU General Public License"
-GNU_LESSER_GENERAL = "GNU Lesser General"
-GCC_RUNTIME_LIB_EXC = "GCC Runtime Library Exception"
-VERSION_2_1 = "version 2.1"
-VERSION_2 = "version 2"
-VERSION_3 = "version 3"
-Licenses = {VERSION_2_1: "v2.1", VERSION_2: "v2", VERSION_3: "v3"}
-CONTRIBUTED_BY = "ontributed by"
+ISO_COPYRIGHT = 'Copyright ISO/IEC'
+COPYRIGHT = 'Copyright (C)'
+GNU_PUBLIC_LICENSE = 'GNU General Public License'
+GNU_LESSER_GENERAL = 'GNU Lesser General'
+GCC_RUNTIME_LIB_EXC = 'GCC Runtime Library Exception'
+VERSION_2_1 = 'version 2.1'
+VERSION_2 = 'version 2'
+VERSION_3 = 'version 3'
+Licenses = {VERSION_2_1: 'v2.1', VERSION_2: 'v2', VERSION_3: 'v3'}
+CONTRIBUTED_BY = 'ontributed by'
 
 
 def printf(fmt, *args):
@@ -63,7 +63,7 @@ def halt_on_error():
 
 
 def basename(f):
-    b = f.split("/")
+    b = f.split('/')
     return b[-1]
 
 
@@ -72,24 +72,24 @@ def analyse_comment(text, f):
     start_date, end_date = None, None
     contribution, summary, lic = None, None, None
     if text.find(ISO_COPYRIGHT) > 0:
-        lic = "BSISO"
+        lic = 'BSISO'
         now = datetime.datetime.now()
         for d in range(1984, now.year+1):
             if text.find(str(d)) > 0:
                 if start_date is None:
                     start_date = str(d)
                 end_date = str(d)
-        return start_date, end_date, "", "", lic
+        return start_date, end_date, '', '', lic
     elif text.find(COPYRIGHT) > 0:
         if text.find(GNU_PUBLIC_LICENSE) > 0:
-            lic = "GPL"
+            lic = 'GPL'
         elif text.find(GNU_LESSER_GENERAL) > 0:
-            lic = "LGPL"
+            lic = 'LGPL'
         for license in Licenses.keys():
             if text.find(license) > 0:
                 lic += Licenses[license]
         if text.find(GCC_RUNTIME_LIB_EXC) > 0:
-            lic += "x"
+            lic += 'x'
         now = datetime.datetime.now()
         for d in range(1984, now.year+1):
             if text.find(str(d)) > 0:
@@ -99,13 +99,13 @@ def analyse_comment(text, f):
         if text.find(CONTRIBUTED_BY) > 0:
             i = text.find(CONTRIBUTED_BY)
             i += len(CONTRIBUTED_BY)
-            j = text.index(". ", i)
+            j = text.index('. ', i)
             contribution = text[i:j]
     if text.find(basename(f)) > 0:
         i = text.find(basename(f))
-        j = text.find(". ", i)
+        j = text.find('. ', i)
         if j < 0:
-            error('summary of the file does not finish with a "."')
+            error('summary of the file does not finish with a '.'')
             summary = text[i:]
         else:
             summary = text[i:j]
@@ -113,27 +113,27 @@ def analyse_comment(text, f):
 
 
 def analyse_header_without_terminator(f, start):
-    text = ""
+    text = ''
     for count, l in enumerate(open(f).readlines()):
         parts = l.split(start)
         if len(parts) > 1:
             line = start.join(parts[1:])
             line = line.strip()
-            text += " "
+            text += ' '
             text += line
-        elif (l.rstrip() != "") and (len(parts[0]) > 0):
+        elif (l.rstrip() != '') and (len(parts[0]) > 0):
             return analyse_comment(text, f), count
     return [None, None, None, None, None], 0
 
 
 def analyse_header_with_terminator(f, start, end):
     inComment = False
-    text = ""
+    text = ''
     for count, line in enumerate(open(f).readlines()):
-        while line != "":
+        while line != '':
             line = line.strip()
             if inComment:
-                text += " "
+                text += ' '
                 pos = line.find(end)
                 if pos >= 0:
                     text += line[:pos]
@@ -141,17 +141,17 @@ def analyse_header_with_terminator(f, start, end):
                     inComment = False
                 else:
                     text += line
-                    line = ""
+                    line = ''
             else:
                 pos = line.find(start)
                 if (pos >= 0) and (len(line) > len(start)):
                     before = line[:pos].strip()
-                    if before != "":
+                    if before != '':
                         return analyse_comment(text, f), count
                     line = line[pos + len(start):]
                     inComment = True
-                elif (line != "") and (line == end):
-                    line = ""
+                elif (line != '') and (line == end):
+                    line = ''
                 else:
                     return analyse_comment(text, f), count
     return [None, None, None, None, None], 0
@@ -170,12 +170,12 @@ def add_stop(sentence):
     if sentence is None:
         return None
     sentence = sentence.rstrip()
-    if (len(sentence) > 0) and (sentence[-1] != "."):
-        return sentence + "."
+    if (len(sentence) > 0) and (sentence[-1] != '.'):
+        return sentence + '.'
     return sentence
 
 
-GPLv3 = """
+GPLv3 = '''
 %s
 
 Copyright (C) %s Free Software Foundation, Inc.
@@ -196,9 +196,9 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GNU Modula-2; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.
-"""
+'''
 
-GPLv3x = """
+GPLv3x = '''
 %s
 
 Copyright (C) %s Free Software Foundation, Inc.
@@ -224,9 +224,9 @@ You should have received a copy of the GNU General Public License and
 a copy of the GCC Runtime Library Exception along with this program;
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.
-"""
+'''
 
-LGPLv3 = """
+LGPLv3 = '''
 %s
 
 Copyright (C) %s Free Software Foundation, Inc.
@@ -246,9 +246,9 @@ Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public License
 along with GNU Modula-2.  If not, see <https://www.gnu.org/licenses/>.
-"""
+'''
 
-BSISO = """
+BSISO = '''
 Library module defined by the International Standard
    Information technology - programming languages
    BS ISO/IEC 10514-1:1996E Part 1: Modula-2, Base Language.
@@ -259,19 +259,19 @@ Library module defined by the International Standard
    It may be freely copied for the purpose of implementation (see page
    707 of the Information technology - Programming languages Part 1:
    Modula-2, Base Language.  BS ISO/IEC 10514-1:1996).
-"""
+'''
 
 templates = {}
-templates["GPLv3"] = GPLv3
-templates["GPLv3x"] = GPLv3x
-templates["LGPLv3"] = LGPLv3
-templates["LGPLv2.1"] = LGPLv3
-templates["BSISO"] = BSISO
+templates['GPLv3'] = GPLv3
+templates['GPLv3x'] = GPLv3x
+templates['LGPLv3'] = LGPLv3
+templates['LGPLv2.1'] = LGPLv3
+templates['BSISO'] = BSISO
 
 
 def write_template(fo, magic, start, end, dates, contribution, summary, lic):
     if lic in templates:
-        if lic == "BSISO":
+        if lic == 'BSISO':
             # non gpl but freely distributed for the implementation of a
             # compiler
             text = templates[lic] % (dates)
@@ -283,30 +283,30 @@ def write_template(fo, magic, start, end, dates, contribution, summary, lic):
             contribution = add_stop(contribution)
             if magic is not None:
                 fo.write(magic)
-                fo.write("\n")
+                fo.write('\n')
             text = templates[lic] % (summary, dates, contribution)
             text = text.rstrip()
         if end is None:
-            text = text.split("\n")
+            text = text.split('\n')
             for line in text:
                 fo.write(start)
-                fo.write(" ")
+                fo.write(' ')
                 fo.write(line)
-                fo.write("\n")
+                fo.write('\n')
         else:
             text = text.lstrip()
             fo.write(start)
-            fo.write(" ")
+            fo.write(' ')
             fo.write(text)
-            fo.write("  ")
+            fo.write('  ')
             fo.write(end)
-            fo.write("\n")
+            fo.write('\n')
         # add a blank comment line for a script for eye candy.
-        if start == "#" and end is None:
+        if start == '#' and end is None:
             fo.write(start)
-            fo.write("\n")
+            fo.write('\n')
     else:
-        error("no template found for: %s\n", lic)
+        error('no template found for: %s\n', lic)
         os.sys.exit(1)
     return fo
 
@@ -316,23 +316,23 @@ def write_boiler_plate(fo, magic, start, end,
     if start_date == end_date:
         dates = start_date
     else:
-        dates = "%s-%s" % (start_date, end_date)
+        dates = '%s-%s' % (start_date, end_date)
     return write_template(fo, magic, start, end,
                           dates, contribution, summary, gpl)
 
 
 def rewrite_file(f, magic, start, end, start_date, end_date,
                  contribution, summary, gpl, lines):
-    text = "".join(open(f).readlines()[lines:])
-    if output_name == "-":
+    text = ''.join(open(f).readlines()[lines:])
+    if output_name == '-':
         fo = sys.stdout
     else:
-        fo = open(f, "w")
+        fo = open(f, 'w')
     fo = write_boiler_plate(fo, magic, start, end,
                             start_date, end_date, contribution, summary, gpl)
     fo.write(text)
     fo.flush()
-    if output_name != "-":
+    if output_name != '-':
         fo.close()
 
 
@@ -346,60 +346,60 @@ def handle_header(f, magic, start, end):
     [start_date, end_date,
      contribution, summary, lic], lines = analyse_header(f, start, end)
     if lic is None:
-        error("%s:1:no GPL found at the top of the file\n", f)
+        error('%s:1:no GPL found at the top of the file\n', f)
     else:
         if args.verbose:
-            printf("copyright: %s\n", lic)
+            printf('copyright: %s\n', lic)
             if (start_date is not None) and (end_date is not None):
                 if start_date == end_date:
-                    printf("dates = %s\n", start_date)
+                    printf('dates = %s\n', start_date)
                 else:
-                    printf("dates = %s-%s\n", start_date, end_date)
+                    printf('dates = %s-%s\n', start_date, end_date)
             if summary is not None:
-                printf("summary: %s\n", summary)
+                printf('summary: %s\n', summary)
             if contribution is not None:
-                printf("contribution: %s\n", contribution)
+                printf('contribution: %s\n', contribution)
         if start_date is None:
-            error("%s:1:no date found in the GPL at the top of the file\n", f)
+            error('%s:1:no date found in the GPL at the top of the file\n', f)
         if args.contribution is None:
-            if contribution == "":
-                error("%s:1:no contribution found in the " +
-                      "GPL at the top of the file\n", f)
+            if contribution == '':
+                error('%s:1:no contribution found in the ' +
+                      'GPL at the top of the file\n', f)
             else:
                 contribution = args.contribution
         if summary is None:
-            if args.summary == "":
-                error("%s:1:no single line summary found in the " +
-                      "GPL at the top of the file\n", f)
+            if args.summary == '':
+                error('%s:1:no single line summary found in the ' +
+                      'GPL at the top of the file\n', f)
             else:
                 summary = args.summary
     if error_count == 0:
         now = datetime.datetime.now()
         if args.no:
-            print(f, "suppressing change as requested: %s-%s %s"
+            print(f, 'suppressing change as requested: %s-%s %s'
                   % (start_date, end_date, lic))
         else:
-            if lic == "BSISO":
+            if lic == 'BSISO':
                 # don't change the BS ISO license!
                 pass
             elif args.extensions:
-                lic = "GPLv3x"
+                lic = 'GPLv3x'
             elif args.gpl3:
-                lic = "GPLv3"
+                lic = 'GPLv3'
             rewrite_file(f, magic, start, end, start_date,
                          str(now.year), contribution, summary, lic, lines)
     else:
-        printf("too many errors, no modifications will occur\n")
+        printf('too many errors, no modifications will occur\n')
 
 
 def bash_tidy(f):
     # bash_tidy tidy up dates using '#' comment
-    handle_header(f, "#!/bin/bash", "#", None)
+    handle_header(f, '#!/bin/bash', '#', None)
 
 
 def python_tidy(f):
     # python_tidy tidy up dates using '#' comment
-    handle_header(f, "#!/usr/bin/env python3", '#', None)
+    handle_header(f, '#!/usr/bin/env python3', '#', None)
 
 
 def bnf_tidy(f):
@@ -421,11 +421,11 @@ def in_tidy(f):
     # in_tidy tidy up dates using '#' as a comment and check
     # the first line for magic number.
     first = open(f).readlines()[0]
-    if (len(first) > 0) and (first[:2] == "#!"):
+    if (len(first) > 0) and (first[:2] == '#!'):
         # magic number found, use this
-        handle_header(f, first, "#", None)
+        handle_header(f, first, '#', None)
     else:
-        handle_header(f, None, "#", None)
+        handle_header(f, None, '#', None)
 
 
 def do_visit(args, dirname, names):
@@ -472,39 +472,39 @@ def find_files():
 def handle_arguments():
     # handle_arguments create and return the args object.
     parser = argparse.ArgumentParser()
-    parser.add_argument("-c", "--contribution",
-                        help="set the contribution string " +
-                        "at the top of the file.",
-                        default="", action="store")
-    parser.add_argument("-d", "--debug", help="turn on internal debugging.",
-                        default=False, action="store_true")
-    parser.add_argument("-f", "--force",
-                        help="force a check to insist that the " +
-                        "contribution, summary and GPL exist.",
-                        default=False, action="store_true")
-    parser.add_argument("-g", "--gplv3", help="change to GPLv3",
-                        default=False, action="store_true")
-    parser.add_argument("-o", "--outputfile", help="set the output file",
-                        default="-", action="store")
-    parser.add_argument("-r", "--recursive",
-                        help="recusively scan directory for known file " +
-                        "extensions (.def, .mod, .c, .h, .py, .in, .sh).",
-                        default=".", action="store")
-    parser.add_argument("-s", "--summary",
-                        help="set the summary line for the file.",
-                        default=None, action="store")
-    parser.add_argument("-u", "--update", help="update all dates.",
-                        default=False, action="store_true")
-    parser.add_argument("-v", "--verbose",
-                        help="display copyright, " +
-                        "date and contribution messages",
-                        action="store_true")
-    parser.add_argument("-x", "--extensions",
-                        help="change to GPLv3 with GCC runtime extensions.",
-                        default=False, action="store_true")
-    parser.add_argument("-N", "--no",
-                        help="do not modify any file.",
-                        action="store_true")
+    parser.add_argument('-c', '--contribution',
+                        help='set the contribution string ' +
+                        'at the top of the file.',
+                        default='', action='store')
+    parser.add_argument('-d', '--debug', help='turn on internal debugging.',
+                        default=False, action='store_true')
+    parser.add_argument('-f', '--force',
+                        help='force a check to insist that the ' +
+                        'contribution, summary and GPL exist.',
+                        default=False, action='store_true')
+    parser.add_argument('-g', '--gplv3', help='change to GPLv3',
+                        default=False, action='store_true')
+    parser.add_argument('-o', '--outputfile', help='set the output file',
+                        default='-', action='store')
+    parser.add_argument('-r', '--recursive',
+                        help='recusively scan directory for known file ' +
+                        'extensions (.def, .mod, .c, .h, .py, .in, .sh).',
+                        default='.', action='store')
+    parser.add_argument('-s', '--summary',
+                        help='set the summary line for the file.',
+                        default=None, action='store')
+    parser.add_argument('-u', '--update', help='update all dates.',
+                        default=False, action='store_true')
+    parser.add_argument('-v', '--verbose',
+                        help='display copyright, ' +
+                        'date and contribution messages',
+                        action='store_true')
+    parser.add_argument('-x', '--extensions',
+                        help='change to GPLv3 with GCC runtime extensions.',
+                        default=False, action='store_true')
+    parser.add_argument('-N', '--no',
+                        help='do not modify any file.',
+                        action='store_true')
     args = parser.parse_args()
     return args
 
@@ -519,15 +519,15 @@ def has_ext(name, ext):
 def single_file(name):
     # single_file scan the single file for a GPL boilerplate which
     # has a GPL, contribution field and a summary heading.
-    if has_ext(name, ".def") or has_ext(name, ".mod"):
+    if has_ext(name, '.def') or has_ext(name, '.mod'):
         m2_tidy(name)
-    elif has_ext(name, ".h") or has_ext(name, ".c") or has_ext(name, ".cc"):
+    elif has_ext(name, '.h') or has_ext(name, '.c') or has_ext(name, '.cc'):
         c_tidy(name)
-    elif has_ext(name, ".in"):
+    elif has_ext(name, '.in'):
         in_tidy(name)
-    elif has_ext(name, ".sh"):
+    elif has_ext(name, '.sh'):
         in_tidy(name)  # uses magic number for actual sh/bash
-    elif has_ext(name, ".py"):
+    elif has_ext(name, '.py'):
         python_tidy(name)
 
 
@@ -539,7 +539,7 @@ def main():
     if args.recursive:
         find_files()
     elif args.inputfile is None:
-        print("an input file must be specified on the command line")
+        print('an input file must be specified on the command line')
     else:
         single_file(args.inputfile)
     halt_on_error()
diff --git a/gcc/m2/tools-src/def2doc.py b/gcc/m2/tools-src/def2doc.py
index 7afba96b668..7aaab6b90af 100755
--- a/gcc/m2/tools-src/def2doc.py
+++ b/gcc/m2/tools-src/def2doc.py
@@ -139,7 +139,24 @@ def remove_fields(file, line):
     output.write(line.rstrip() + '\n')
 
 
-def check_index(line):
+def emit_index(entry, tag, previous):
+    if args.texinfo:
+        if tag == '':
+            output.write('@findex ' + entry.rstrip() + '\n')
+        else:
+            output.write('@findex ' + entry.rstrip() + ' ' + tag + '\n')
+    elif args.sphinx:
+        if tag == '':
+            output.write('.. index::')
+            output.write(' ' * 3 + entry.rstrip() + '\n')
+        else:
+            output.write('.. index::')
+            output.write(' ' * 3 + 'pair: ' + entry.rstrip() + '; ' + tag + '\n')
+        if previous != '':
+            output.write(previous + '\n')
+
+
+def check_index(line, current):
     # check_index - create an index entry for a PROCEDURE, TYPE, CONST or VAR.
     global in_var, in_type, in_const
 
@@ -177,25 +194,24 @@ def check_index(line):
             word = word.lstrip()
             if word != '':
                 if word.find(':') == -1:
-                    output.write('@findex ' + word + ' (var)\n')
+                    emit_index(word, '(var)', current)
                 elif len(word) > 0:
                     var = word.split(':')
                     if len(var) > 0:
-                        output.write('@findex ' + var[0] + ' (var)\n')
+                        emit_index(var[0], '(var)', current)
 
     if in_type:
         words = line.lstrip()
         if words.find('=') != -1:
             word = words.split('=')
             if (len(word[0]) > 0) and (word[0][0] != '_'):
-                output.write('@findex ' + word[0].rstrip() + ' (type)\n')
+                emit_index(word[0].rstrip(), '(type)', current)
         else:
             word = words.split()
             if (len(word) > 1) and (word[1] == ';'):
                 # hidden type
                 if (len(word[0]) > 0) and (word[0][0] != '_'):
-                    output.write('@findex ' + word[0].rstrip())
-                    output.write(' (type)\n')
+                    emit_index(word[0].rstrip(), '(type)', current)
     if in_const:
         words = line.split(';')
         for word in words:
@@ -204,7 +220,7 @@ def check_index(line):
                 if word.find('=') != -1:
                     var = word.split('=')
                     if len(var) > 0:
-                        output.write('@findex ' + var[0] + ' (const)\n')
+                        emit_index(var[0], '(const)', current)
     if procedure != '':
         name = procedure.split('(')
         if name[0] != '':
@@ -212,10 +228,77 @@ def check_index(line):
             if proc[-1] == ';':
                 proc = proc[:-1]
             if proc != '':
-                output.write('@findex ' + proc + '\n')
+                emit_index(proc, '', current)
 
 
-def parse_definition(dir, source, build, file, needPage):
+def emit_texinfo_content(f, line):
+    output.write(line.rstrip() + '\n')
+    line = f.readline()
+    if len(line.rstrip()) == 0:
+        output.write('\n')
+        line = f.readline()
+        if (line.find('(*') != -1):
+            remove_fields(f, line)
+        else:
+            output.write(line.rstrip() + '\n')
+    else:
+        output.write(line.rstrip() + '\n')
+    line = f.readline()
+    while line:
+        line = line.rstrip()
+        check_index(line, '')
+        output.write(str.replace(str.replace(line, '{', '@{'), '}', '@}'))
+        output.write('\n')
+        line = f.readline()
+    return f
+
+
+def emit_sphinx_content(f, line):
+    output.write('.. code-block:: modula2\n')
+    indent = ' ' * 4
+    output.write(indent + line.rstrip() + '\n')
+    line = f.readline()
+    if len(line.rstrip()) == 0:
+        output.write('\n')
+        line = f.readline()
+        if (line.find('(*') != -1):
+            remove_fields(f, line)
+        else:
+            output.write(indent + line.rstrip() + '\n')
+    else:
+        output.write(indent + line.rstrip() + '\n')
+    line = f.readline()
+    while line:
+        line = line.rstrip()
+        check_index(line, '.. code-block:: modula2')
+        output.write(indent + line + '\n')
+        line = f.readline()
+    return f
+
+
+def emit_example_content(f, line):
+    if args.texinfo:
+        return emit_texinfo_content(f, line)
+    elif args.sphinx:
+        return emit_sphinx_content(f, line)
+
+
+def emit_example_begin():
+    if args.texinfo:
+        output.write('@example\n')
+
+
+def emit_example_end():
+    if args.texinfo:
+        output.write('@end example\n')
+
+
+def emit_page(need_page):
+    if need_page and args.texinfo:
+        output.write('@page\n')
+
+
+def parse_definition(dir, source, build, file, need_page):
     # parse_definition reads a definition module and creates
     # indices for procedures, constants, variables and types.
     output.write('\n')
@@ -227,28 +310,10 @@ def parse_definition(dir, source, build, file, needPage):
             line = f.readline()
         while (line.find('DEFINITION') == -1):
             line = f.readline()
-        output.write('@example\n')
-        output.write(line.rstrip() + '\n')
-        line = f.readline()
-        if len(line.rstrip()) == 0:
-            output.write('\n')
-            line = f.readline()
-            if (line.find('(*') != -1):
-                remove_fields(f, line)
-            else:
-                output.write(line.rstrip() + '\n')
-        else:
-            output.write(line.rstrip() + '\n')
-        line = f.readline()
-        while line:
-            line = line.rstrip()
-            check_index(line)
-            output.write(str.replace(str.replace(line, '{', '@{'), '}', '@}'))
-            output.write('\n')
-            line = f.readline()
-        output.write('@end example\n')
-        if needPage:
-            output.write('@page\n')
+        emit_example_begin()
+        f = emit_example_content(f, line)
+        emit_example_end()
+        emit_page(need_page)
 
 
 def parse_modules(up, dir, build, source, list_of_modules):
@@ -339,8 +404,14 @@ def display_modules(up, dir, build, source):
     # display_modules walks though the files in dir and parses
     # definition modules and includes README.texi
     if check_directory(dir, build, source):
-        if found_file(dir, build, source, 'README.texi'):
-            do_cat(find_file(dir, build, source, 'README.texi'))
+        if args.texinfo:
+            ext = ".texi"
+        elif args.sphinx:
+            ext = ".rst"
+        else:
+            ext = ""
+        if found_file(dir, build, source, 'README' + ext):
+            do_cat(find_file(dir, build, source, 'README' + ext))
         module_menu(dir, build, source)
         list_of_files = []
         if os.path.exists(os.path.join(source, dir)):
@@ -402,7 +473,7 @@ def handle_file():
         display_library_class()
     else:
         parse_definition('.', args.sourcedir, args.builddir,
-                        args.inputfile, False)
+                         args.inputfile, False)
 
 
 def main():
diff --git a/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/c.def b/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/c.def
index 8a1c8b815ef..ca6f94e20d8 100644
--- a/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/c.def
+++ b/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/c.def
@@ -21,6 +21,8 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 
 DEFINITION MODULE FOR "C" c ;
 
+EXPORT UNQUALIFIED funcString ;
+
 PROCEDURE funcString (s: ARRAY OF CHAR) : INTEGER ;
 
 END c.
diff --git a/gcc/testsuite/gm2/examples/callingC/run/pass/c.def b/gcc/testsuite/gm2/examples/callingC/run/pass/c.def
index 87de68a635d..828ed3a7eb5 100644
--- a/gcc/testsuite/gm2/examples/callingC/run/pass/c.def
+++ b/gcc/testsuite/gm2/examples/callingC/run/pass/c.def
@@ -26,6 +26,8 @@ DEFINITION MODULE FOR "C" c ;
     Description: tiny example of C definition module.
 *)
 
+EXPORT UNQUALIFIED bar ;
+
 PROCEDURE bar (a, b: ARRAY OF CHAR) : BOOLEAN ;
 
 END c.
diff --git a/gcc/testsuite/gm2/extensions/run/pass/cvararg.def b/gcc/testsuite/gm2/extensions/run/pass/cvararg.def
index ddfe72e07a1..7bd582fe5f5 100644
--- a/gcc/testsuite/gm2/extensions/run/pass/cvararg.def
+++ b/gcc/testsuite/gm2/extensions/run/pass/cvararg.def
@@ -19,6 +19,8 @@ DEFINITION MODULE FOR "C" cvararg ;
 
 FROM SYSTEM IMPORT ADDRESS ;
 
+EXPORT UNQUALIFIED func, funcptr, funcptrint ;
+
 PROCEDURE func (c: INTEGER; ...) : INTEGER ;
 PROCEDURE funcptr (c: INTEGER; ...) : INTEGER ;
 PROCEDURE funcptrint (p: ADDRESS; ...) : INTEGER ;
diff --git a/gcc/testsuite/gm2/pim/run/pass/minhello.mod b/gcc/testsuite/gm2/pim/run/pass/minhello.mod
new file mode 100644
index 00000000000..0a69716746f
--- /dev/null
+++ b/gcc/testsuite/gm2/pim/run/pass/minhello.mod
@@ -0,0 +1,12 @@
+MODULE minhello ;
+
+(* This test is useful to test the linking to ensure that the
+   application module is called after all modules are initialized
+   even if the application module only imports from a definition
+   for "C".  *)
+
+FROM libc IMPORT printf ;
+
+BEGIN
+   printf ("hello world\n")
+END minhello.
diff --git a/gcc/testsuite/gm2/switches/check-all/run/fail/tinyrange.mod b/gcc/testsuite/gm2/switches/check-all/run/fail/tinyrange.mod
new file mode 100644
index 00000000000..bc25483597a
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/check-all/run/fail/tinyrange.mod
@@ -0,0 +1,17 @@
+MODULE tinyrange ;
+
+(* This test is useful to check that the runtime system starts the
+   application after the runtime.  The import list here is minimal
+   (and only from a definition for "C") thus the compiler will not
+   see the application in the rest of the modula2 import graph.
+   M2Dependent.mod will have to force the application module to the
+   end of the initialization ordered list.  *)
+
+FROM libc IMPORT printf ;
+
+VAR
+   i: INTEGER ;
+BEGIN
+   i := MIN (INTEGER) ;
+   DEC (i)
+END tinyrange.
diff --git a/gcc/testsuite/gm2/switches/whole-program/pass/run/hello.mod b/gcc/testsuite/gm2/switches/whole-program/pass/run/hello.mod
new file mode 100644
index 00000000000..75d0f651c39
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/whole-program/pass/run/hello.mod
@@ -0,0 +1,7 @@
+MODULE hello ;
+
+FROM libc IMPORT printf ;
+
+BEGIN
+   printf ("hello world\n")
+END hello.
diff --git a/gcc/testsuite/gm2/switches/whole-program/pass/run/hello2.mod b/gcc/testsuite/gm2/switches/whole-program/pass/run/hello2.mod
new file mode 100644
index 00000000000..642752ef2a4
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/whole-program/pass/run/hello2.mod
@@ -0,0 +1,7 @@
+MODULE hello2 ;
+
+FROM StrIO IMPORT WriteString, WriteLn ;
+
+BEGIN
+   WriteString ("hello world") ; WriteLn
+END hello2.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-11-15 19:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-15 19:13 [gcc/devel/modula-2] Bugfix -fm2-whole-program linking Gaius Mulley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).