diff --git i/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h
index aa2b0f782fa..f11cf87f190 100644
--- i/gcc/cp/cp-tree.h
+++ w/gcc/cp/cp-tree.h
@@ -7916,6 +7916,9 @@ extern tree mangle_template_parm_object		(tree);
 extern char *get_mangled_vtable_map_var_name    (tree);
 extern bool mangle_return_type_p		(tree);
 extern tree mangle_decomp			(tree, vec<tree> &);
+extern void mangle_module_substitution		(int);
+extern void mangle_identifier			(char, tree);
+extern tree mangle_module_global_init		(int);
 
 /* in dump.c */
 extern bool cp_dump_tree			(void *, tree);
diff --git i/gcc/cp/mangle.c w/gcc/cp/mangle.c
index 5548e51d39d..c1d9c737a16 100644
--- i/gcc/cp/mangle.c
+++ w/gcc/cp/mangle.c
@@ -117,6 +117,9 @@ struct GTY(()) globals {
 
   /* True if the mangling will be different in C++17 mode.  */
   bool need_cxx17_warning;
+
+  /* True if we mangled a module name.  */
+  bool mod;
 };
 
 static GTY (()) globals G;
@@ -832,6 +835,62 @@ write_encoding (const tree decl)
     }
 }
 
+/* Interface to substitution and identifer mangling, used by the
+   module name mangler.  */
+
+void
+mangle_module_substitution (int v)
+{
+  if (v < 10)
+    {
+      write_char ('_');
+      write_char ('0' + v);
+    }
+  else
+    {
+      write_char ('W');
+      write_unsigned_number (v - 10);
+      write_char ('_');
+    }
+}
+
+void
+mangle_identifier (char c, tree id)
+{
+  if (c)
+    write_char (c);
+  write_source_name (id);
+}
+
+/* If the outermost non-namespace context (including DECL itself) is
+   a module-linkage decl, mangle the module information.  For module
+   global initializers we need to include the partition part.
+
+   <module-name> ::= W <module-id>+ E
+   <module-id> :: <unqualified-name>
+               || _ <digit>  ;; short backref
+	       || W <number> _  ;; long backref
+               || P <module-id> ;; partition introducer
+*/
+
+static void
+write_module (int m, bool include_partition)
+{
+  G.mod = true;
+
+  write_char ('W');
+  mangle_module (m, include_partition);
+  write_char ('E');
+}
+
+static void
+maybe_write_module (tree decl)
+{
+  int m = get_originating_module (decl, true);
+  if (m >= 0)
+    write_module (m, false);
+}
+
 /* Lambdas can have a bit more context for mangling, specifically VAR_DECL
    or PARM_DECL context, which doesn't belong in DECL_CONTEXT.  */
 
@@ -894,6 +953,9 @@ write_name (tree decl, const int ignore_local_scope)
       decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
     }
 
+  if (modules_p ())
+    maybe_write_module (decl);
+
   context = decl_mangling_context (decl);
 
   gcc_assert (context != NULL_TREE);
@@ -3825,14 +3887,13 @@ start_mangling (const tree entity)
   G.entity = entity;
   G.need_abi_warning = false;
   G.need_cxx17_warning = false;
+  G.mod = false;
   obstack_free (&name_obstack, name_base);
   mangle_obstack = &name_obstack;
   name_base = obstack_alloc (&name_obstack, 0);
 }
 
-/* Done with mangling. If WARN is true, and the name of G.entity will
-   be mangled differently in a future version of the ABI, issue a
-   warning.  */
+/* Done with mangling.  Release the data.  */
 
 static void
 finish_mangling_internal (void)
@@ -3840,6 +3901,9 @@ finish_mangling_internal (void)
   /* Clear all the substitutions.  */
   vec_safe_truncate (G.substitutions, 0);
 
+  if (G.mod)
+    mangle_module_fini ();
+
   /* Null-terminate the string.  */
   write_char ('\0');
 }
@@ -3884,6 +3948,20 @@ init_mangle (void)
   subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream");
 }
 
+/* Generate a mangling for MODULE's global initializer fn.  */
+
+tree
+mangle_module_global_init (int module)
+{
+  start_mangling (NULL_TREE);
+
+  write_string ("_ZGI");
+  write_module (module, true);
+  write_char ('v');
+
+  return finish_mangling_get_identifier ();
+}
+
 /* Generate the mangled name of DECL.  */
 
 static tree
diff --git i/gcc/cp/module.cc w/gcc/cp/module.cc
index 91a16815811..24580c70907 100644
--- i/gcc/cp/module.cc
+++ w/gcc/cp/module.cc
@@ -70,6 +70,23 @@ get_module (tree, module_state *, bool)
   return nullptr;
 }
 
+
+void
+mangle_module (int, bool)
+{
+}
+
+void
+mangle_module_fini ()
+{
+}
+
+int
+get_originating_module (tree, bool)
+{
+  return 0;
+}
+
 module_state *
 preprocess_module (module_state *, unsigned, bool, bool, bool, cpp_reader *)
 {
