aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/mangle.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2021-01-03 21:40:04 +0100
committerThomas Koenig <tkoenig@gcc.gnu.org>2021-01-03 21:40:04 +0100
commitafae4a55ccaa0de95ea11e5f634084db6ab2f444 (patch)
treed632cc867d10410ba9fb750523be790b86846ac4 /gcc/cp/mangle.c
parent9d9a82ec8478ff52c7a9d61f58cd2a7b6295b5f9 (diff)
parentd2eb616a0f7bea78164912aa438c29fe1ef5774a (diff)
downloadgcc-afae4a55ccaa0de95ea11e5f634084db6ab2f444.zip
gcc-afae4a55ccaa0de95ea11e5f634084db6ab2f444.tar.gz
gcc-afae4a55ccaa0de95ea11e5f634084db6ab2f444.tar.bz2
Merge branch 'master' into devel/coarray_native
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r--gcc/cp/mangle.c121
1 files changed, 112 insertions, 9 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 9fd3001..7c32e22 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.
+
+ <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);
@@ -2815,7 +2877,10 @@ write_member_name (tree member)
write_unqualified_id (member);
}
else if (DECL_P (member))
- write_unqualified_name (member);
+ {
+ gcc_assert (!DECL_OVERLOADED_OPERATOR_P (member));
+ write_unqualified_name (member);
+ }
else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
{
tree name = TREE_OPERAND (member, 0);
@@ -3049,11 +3114,30 @@ write_expression (tree expr)
else
goto normal_expr;
}
- else if (TREE_CODE (expr) == ALIGNOF_EXPR
- && TYPE_P (TREE_OPERAND (expr, 0)))
+ else if (TREE_CODE (expr) == ALIGNOF_EXPR)
{
- write_string ("at");
- write_type (TREE_OPERAND (expr, 0));
+ if (!ALIGNOF_EXPR_STD_P (expr))
+ {
+ if (abi_warn_or_compat_version_crosses (15))
+ G.need_abi_warning = true;
+ if (abi_version_at_least (15))
+ {
+ /* We used to mangle __alignof__ like alignof. */
+ write_string ("v111__alignof__");
+ if (TYPE_P (TREE_OPERAND (expr, 0)))
+ write_type (TREE_OPERAND (expr, 0));
+ else
+ write_expression (TREE_OPERAND (expr, 0));
+ return;
+ }
+ }
+ if (TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("at");
+ write_type (TREE_OPERAND (expr, 0));
+ }
+ else
+ goto normal_expr;
}
else if (code == SCOPE_REF
|| code == BASELINK)
@@ -3081,6 +3165,7 @@ write_expression (tree expr)
write_expression (member);
else
{
+ gcc_assert (code != BASELINK || BASELINK_QUALIFIED_P (expr));
write_string ("sr");
write_type (scope);
write_member_name (member);
@@ -3263,7 +3348,9 @@ write_expression (tree expr)
}
else if (dependent_name (expr))
{
- write_unqualified_id (dependent_name (expr));
+ tree name = dependent_name (expr);
+ gcc_assert (!IDENTIFIER_ANY_OP_P (name));
+ write_unqualified_id (name);
}
else
{
@@ -3806,14 +3893,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)
@@ -3821,6 +3907,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');
}
@@ -3865,6 +3954,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