diff options
author | Nathan Sidwell <nathan@acm.org> | 2022-03-02 19:13:43 -0500 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2022-03-04 10:15:18 -0500 |
commit | 73baba1ae1b8f3618c2d3b674117b8a462e0ca76 (patch) | |
tree | 6bef001d2cbd8c83d7487248c9e6436e2a46da0d /gcc/cp/mangle.cc | |
parent | f1b3e3853329b58fb2e50c17487df2ecbc4a5608 (diff) | |
download | gcc-73baba1ae1b8f3618c2d3b674117b8a462e0ca76.zip gcc-73baba1ae1b8f3618c2d3b674117b8a462e0ca76.tar.gz gcc-73baba1ae1b8f3618c2d3b674117b8a462e0ca76.tar.bz2 |
c++: New module mangling ABI
This implements a new module mangling ABI as the original one has a
few issues:
a) it was not demangleable (oops)
b) implemented a weak ownership model.
This implements a strong ownership model, so that exported entities
from named modules are mangled to include their module attachment.
This gives more informative linker diagnostics and better module
isolation. Weak ownership was hoped to allow backwards compatibility
with non-modular code, but in practice was very brittle, and C++20
added new semantics for linkage declarations that cover the needed
functionality.
FAOD Clang is also moving to this ABI and documentation will be added
to the Itanium ABI specification.
gcc/cp/
* cp-tree.h (mangle_identifier): Replace with ...
(mangle_module_component): ... this.
* mangle.cc (dump_substitution_candidates): Adjust.
(add_substitution): Likewise.
(find_substitution): Likewise.
(unmangled_name_p): Likewise.
(mangle_module_substitution): Reimplement.
(mangle_module_component): New.
(write_module, maybe_write_module): Adjust.
(write_name): Drop modules here.
(write_unqualified): Do them here instead.
(mangle_global_init): Adjust.
* module.cc (module_state::mangle): Adjust.
(mangle_module): Likewise.
(get_originating_module): Adjust.
gcc/testsuite/
* g++.dg/modules/fn-inline-1_b.C: Adjust.
* g++.dg/modules/fn-inline-1_c.C: Adjust.
* g++.dg/modules/imp-inline-1_a.C: Adjust.
* g++.dg/modules/imp-inline-1_b.C: Adjust.
* g++.dg/modules/init-2_a.C: Adjust.
* g++.dg/modules/init-2_b.C: Adjust.
* g++.dg/modules/init-2_c.C: Adjust.
* g++.dg/modules/member-def-2_d.C: Adjust.
* g++.dg/modules/mod-sym-1.C: Adjust.
* g++.dg/modules/mod-sym-2.C: Adjust.
* g++.dg/modules/mod-sym-3.C: Adjust.
* g++.dg/modules/sym-subst-1.C: Adjust.
* g++.dg/modules/sym-subst-2_b.C: Adjust.
* g++.dg/modules/sym-subst-3_a.C: Adjust.
* g++.dg/modules/sym-subst-3_b.C: Adjust.
* g++.dg/modules/sym-subst-4.C: Adjust.
* g++.dg/modules/sym-subst-5.C: Adjust.
* g++.dg/modules/sym-subst-6.C: Adjust.
* g++.dg/modules/tpl-spec-1_a.C: Adjust.
* g++.dg/modules/tpl-spec-2_b.C: Adjust.
* g++.dg/modules/tpl-spec-2_d.C: Adjust.
* g++.dg/modules/tpl-spec-3_a.C: Adjust.
* g++.dg/modules/virt-1_a.C: Adjust.
* g++.dg/modules/virt-2_a.C: Adjust.
* g++.dg/modules/virt-2_b.C: Adjust.
* g++.dg/modules/virt-2_c.C: Adjust.
* g++.dg/modules/vtt-1_a.C: Adjust.
* g++.dg/modules/vtt-1_b.C: Adjust.
Diffstat (limited to 'gcc/cp/mangle.cc')
-rw-r--r-- | gcc/cp/mangle.cc | 124 |
1 files changed, 67 insertions, 57 deletions
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index a20f0e0..6657ce4 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -102,7 +102,8 @@ along with GCC; see the file COPYING3. If not see /* Things we only need one of. This module is not reentrant. */ struct GTY(()) globals { /* An array of the current substitution candidates, in the order - we've seen them. */ + we've seen them. Contains NULLS, which correspond to module + substitutions. */ vec<tree, va_gc> *substitutions; /* The entity that is being mangled. */ @@ -318,20 +319,26 @@ dump_substitution_candidates (void) if (i > 0) fprintf (stderr, " "); - if (DECL_P (el)) + if (!el) + name = "module"; + else if (DECL_P (el)) name = IDENTIFIER_POINTER (DECL_NAME (el)); else if (TREE_CODE (el) == TREE_LIST) name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el))); else if (TYPE_NAME (el)) name = TYPE_NAME_STRING (el); fprintf (stderr, " S%d_ = ", i - 1); - if (TYPE_P (el) && - (CP_TYPE_RESTRICT_P (el) - || CP_TYPE_VOLATILE_P (el) - || CP_TYPE_CONST_P (el))) - fprintf (stderr, "CV-"); - fprintf (stderr, "%s (%s at %p)\n", - name, get_tree_code_name (TREE_CODE (el)), (void *) el); + if (el) + { + if (TYPE_P (el) && + (CP_TYPE_RESTRICT_P (el) + || CP_TYPE_VOLATILE_P (el) + || CP_TYPE_CONST_P (el))) + fprintf (stderr, "CV-"); + fprintf (stderr, "%s (%s at %p)", + name, get_tree_code_name (TREE_CODE (el)), (void *) el); + } + fprintf (stderr, "\n"); } } @@ -443,11 +450,12 @@ add_substitution (tree node) tree candidate; FOR_EACH_VEC_SAFE_ELT (G.substitutions, i, candidate) - { - gcc_assert (!(DECL_P (node) && node == candidate)); - gcc_assert (!(TYPE_P (node) && TYPE_P (candidate) - && same_type_p (node, candidate))); - } + if (candidate) + { + gcc_assert (!(DECL_P (node) && node == candidate)); + gcc_assert (!(TYPE_P (node) && TYPE_P (candidate) + && same_type_p (node, candidate))); + } } /* Put the decl onto the varray of substitution candidates. */ @@ -669,20 +677,21 @@ find_substitution (tree node) tags = get_abi_tags (type); /* Now check the list of available substitutions for this mangling operation. */ - if (!abbr || tags) for (i = 0; i < size; ++i) - { - tree candidate = (*G.substitutions)[i]; - /* NODE is a matched to a candidate if it's the same decl node or - if it's the same type. */ - if (decl == candidate - || (TYPE_P (candidate) && type && TYPE_P (node) - && same_type_p (type, candidate)) - || NESTED_TEMPLATE_MATCH (node, candidate)) + if (!abbr || tags) + for (i = 0; i < size; ++i) + if (tree candidate = (*G.substitutions)[i]) { - write_substitution (i); - return 1; + /* NODE is a matched to a candidate if it's the same decl node or + if it's the same type. */ + if (decl == candidate + || (TYPE_P (candidate) && type && TYPE_P (node) + && same_type_p (type, candidate)) + || NESTED_TEMPLATE_MATCH (node, candidate)) + { + write_substitution (i); + return 1; + } } - } if (!abbr) /* No substitution found. */ @@ -735,6 +744,10 @@ unmangled_name_p (const tree decl) if (get_abi_tags (decl)) return false; + // Declarations attached to a named module are mangled + if (modules_p () && get_originating_module (decl, true) >= 0) + return false; + /* The names of non-static global variables aren't mangled. */ return true; } @@ -853,51 +866,49 @@ write_encoding (const tree decl) 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 ('_'); - } + write_substitution (v - 1); } -void -mangle_identifier (char c, tree id) +int +mangle_module_component (tree comp, bool partition_p) { - if (c) - write_char (c); - write_source_name (id); + write_char ('W'); + if (partition_p) + write_char ('P'); + write_source_name (comp); + + // Module substitutions use the same number-space as entity + // substitutions, but are orthogonal. + vec_safe_push (G.substitutions, NULL_TREE); + return G.substitutions->length (); } /* 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 + <module-name> ::= <module-sub> + || <subst> + || <module-name> <module-sub> + <module-sub> :: W [P] <unqualified-name> */ 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) { + if (!DECL_NAMESPACE_SCOPE_P (decl)) + return; + + if (TREE_CODE (decl) == NAMESPACE_DECL && DECL_NAME (decl)) + return; + int m = get_originating_module (decl, true); if (m >= 0) write_module (m, false); @@ -965,9 +976,6 @@ 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); @@ -1356,10 +1364,10 @@ find_decomp_unqualified_name (tree decl, size_t *len) /* We don't need to handle thunks, vtables, or VTTs here. Those are mangled through special entry points. - <unqualified-name> ::= <operator-name> + <unqualified-name> ::= [<module-name>] <operator-name> ::= <special-name> - ::= <source-name> - ::= <unnamed-type-name> + ::= [<module-name>] <source-name> + ::= [<module-name>] <unnamed-type-name> ::= <local-source-name> <local-source-name> ::= L <source-name> <discriminator> */ @@ -1385,6 +1393,9 @@ write_unqualified_name (tree decl) { MANGLE_TRACE_TREE ("unqualified-name", decl); + if (modules_p ()) + maybe_write_module (decl); + if (identifier_p (decl)) { write_unqualified_id (decl); @@ -3996,7 +4007,6 @@ mangle_module_global_init (int module) write_string ("_ZGI"); write_module (module, true); - write_char ('v'); return finish_mangling_get_identifier (); } |