From 210d143dbc575f293affbd55417505bcb8257d74 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 8 Dec 2020 06:07:19 -0800 Subject: [PATCH] c++: Mangling for modules This is the mangling changes for modules. These were developed in collaboration with clang, which also implemements the same ABI (or plans to, I do not think the global init is in clang). The global init mangling is captured in https://github.com/itanium-cxx-abi/cxx-abi/issues/99 gcc/cp/ * cp-tree.h (mangle_module_substitution, mangle_identifier) (mangle_module_global_init): Declare. * mangle.c (struct globals): Add mod field. (mangle_module_substitution, mangle_identifier) (mangle_module_global_init): Define. (write_module, maybe_write_module): New. (write_name): Call it. (start_mangling): Clear mod field. (finish_mangling_internal): Adjust. * module.cc (mangle_module, mangle_module_fini) (get_originating_module): Stubs. --- gcc/cp/cp-tree.h | 3 ++ gcc/cp/mangle.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++-- gcc/cp/module.cc | 17 ++++++++++ 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index aa2b0f782fa..f11cf87f190 100644 --- a/gcc/cp/cp-tree.h +++ b/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 &); +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 a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 5548e51d39d..c1d9c737a16 100644 --- a/gcc/cp/mangle.c +++ b/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. + + ::= W + E + :: + || _ ;; short backref + || W _ ;; long backref + || P ;; 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 a/gcc/cp/module.cc b/gcc/cp/module.cc index 91a16815811..24580c70907 100644 --- a/gcc/cp/module.cc +++ b/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 *) { -- 2.30.2