/* The following apply to VAR, FUNCTION, TYPE, CONCEPT, & NAMESPACE
decls. */
+ // FIXME: Purview and Attachment are not the same thing, due to
+ // linkage-declarations. The modules code presumes they are the
+ // same. (For context, linkage-decl semantics was a very late
+ // change). We need a module_attachment_p flag, and this will allow
+ // some simplification of how we handle header unit entities.
+ // Hurrah!
unsigned module_purview_p : 1; /* in module purview (not GMF) */
unsigned module_import_p : 1; /* from an import */
unsigned module_entity_p : 1; /* is in the entitity ary &
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 int mangle_module_component (tree id, bool partition);
extern tree mangle_module_global_init (int);
/* in dump.cc */
/* 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. */
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");
}
}
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. */
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. */
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;
}
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);
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);
/* 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> */
{
MANGLE_TRACE_TREE ("unqualified-name", decl);
+ if (modules_p ())
+ maybe_write_module (decl);
+
if (identifier_p (decl))
{
write_unqualified_id (decl);
write_string ("_ZGI");
write_module (module, true);
- write_char ('v');
return finish_mangling_get_identifier ();
}
module_state::mangle (bool include_partition)
{
if (subst)
- mangle_module_substitution (subst - 1);
+ mangle_module_substitution (subst);
else
{
if (parent)
parent->mangle (include_partition);
- if (include_partition || !is_partition ())
+ if (include_partition || !is_partition ())
{
- char p = 0;
- // Partitions are significant for global initializer functions
- if (is_partition () && !parent->is_partition ())
- p = 'P';
+ // Partitions are significant for global initializer
+ // functions
+ bool partition = is_partition () && !parent->is_partition ();
+ subst = mangle_module_component (name, partition);
substs.safe_push (this);
- subst = substs.length ();
- mangle_identifier (p, name);
}
}
}
{
module_state *imp = (*modules)[mod];
+ gcc_checking_assert (!imp->is_header ());
+
if (!imp->name)
/* Set when importing the primary module interface. */
imp = imp->parent;
if (!DECL_LANG_SPECIFIC (not_tmpl))
return for_mangle ? -1 : 0;
- if (for_mangle
- && (DECL_MODULE_EXPORT_P (owner) || !DECL_MODULE_PURVIEW_P (not_tmpl)))
+ if (for_mangle && !DECL_MODULE_PURVIEW_P (not_tmpl))
return -1;
- if (!DECL_MODULE_IMPORT_P (not_tmpl))
- return 0;
+ int mod = !DECL_MODULE_IMPORT_P (not_tmpl) ? 0 : get_importing_module (owner);
- return get_importing_module (owner);
+ if (for_mangle && (*modules)[mod]->is_header ())
+ return -1;
+
+ return mod;
}
unsigned
return frob (n, a);
}
-// { dg-final { scan-assembler "_ZW3bobE4frobii:" } }
-// { dg-final { scan-assembler ".weak(_definition)?\[\t ]*_?_ZW3bobE4frobii" } }
-// { dg-final { scan-assembler "_Z4Frobii:" } }
+// { dg-final { scan-assembler "_ZW3bob4frobii:" } }
+// { dg-final { scan-assembler ".weak(_definition)?\[\t ]*_?_ZW3bob4frobii" } }
+// { dg-final { scan-assembler "_ZW3bob4Frobii:" } }
return 0;
}
-// { dg-final { scan-assembler "_Z4frobi:" } }
-// { dg-final { scan-assembler ".weak(_definition)?\[\t ]*_?_Z4frobi" } }
+// { dg-final { scan-assembler "_ZW3bob4frobi:" } }
+// { dg-final { scan-assembler ".weak(_definition)?\[\t ]*_?_ZW3bob4frobi" } }
}
// { dg-final { scan-assembler-not {_ZN3Bob4frobEv:} } }
-// { dg-final { scan-assembler-not {_ZN4Bill4frobEv:} } }
-// { dg-final { scan-assembler {_ZN4Bill3dobEv:} } }
+// { dg-final { scan-assembler-not {_ZNW3Foo4Bill4frobEv:} } }
+// { dg-final { scan-assembler {_ZNW3Foo4Bill3dobEv:} } }
}
// { dg-final { scan-assembler {_ZN3Bob4frobEv:} } }
-// { dg-final { scan-assembler {_ZN4Bill4frobEv:} } }
-// { dg-final { scan-assembler-not {_ZN4Bill3dobEv:} } }
-// { dg-final { scan-assembler {_Z3GMFv:} } }
+// { dg-final { scan-assembler {_ZNW3Foo4Bill4frobEv:} } }
+// { dg-final { scan-assembler-not {_ZNW3Foo4Bill3dobEv:} } }
+// { dg-final { scan-assembler {_ZW3Foo3GMFv:} } }
// { dg-final { scan-assembler {call[ \t]+_?_ZN3Bob4frobEv} { target i?86-*-* x86_64-*-* } } }
-// { dg-final { scan-assembler {call[ \t]+_?_Z3GMFv} { target i?86-*-* x86_64-*-* } } }
-// { dg-final { scan-assembler {call[ \t]+_?_ZN4Bill3dobEv} { target i?86-*-* x86_64-*-* } } }
-// { dg-final { scan-assembler {call[ \t]+_?_ZN4Bill4frobEv} { target i?86-*-* x86_64-*-* } } }
+// { dg-final { scan-assembler {call[ \t]+_?_ZW3Foo3GMFv} { target i?86-*-* x86_64-*-* } } }
+// { dg-final { scan-assembler {call[ \t]+_?_ZNW3Foo4Bill3dobEv} { target i?86-*-* x86_64-*-* } } }
+// { dg-final { scan-assembler {call[ \t]+_?_ZNW3Foo4Bill4frobEv} { target i?86-*-* x86_64-*-* } } }
export module Foo;
// { dg-module-cmi Foo }
-// { dg-final { scan-assembler {_ZGIW3FooEv:} } }
+// { dg-final { scan-assembler {_ZGIW3Foo:} } }
import Foo;
-// { dg-final { scan-assembler {_?_ZGIW3BarEv:} } }
-// { dg-final { scan-assembler {call[ \t]+_?_ZGIW3FooEv} { target i?86-*-* x86_64-*-* } } }
+// { dg-final { scan-assembler {_?_ZGIW3Bar:} } }
+// { dg-final { scan-assembler {call[ \t]+_?_ZGIW3Foo} { target i?86-*-* x86_64-*-* } } }
import Bar;
// We know Bar imports Foo, so only call Bar's Global Init
-// { dg-final { scan-assembler {call[ \t]+_?_ZGIW3BarEv} { target i?86-*-* x86_64-*-* } } }
-// { dg-final { scan-assembler-not {call[ \t]+_?_ZGIW3FooEv} { target i?86-*-* x86_64-*-* } } }
+// { dg-final { scan-assembler {call[ \t]+_?_ZGIW3Bar} { target i?86-*-* x86_64-*-* } } }
+// { dg-final { scan-assembler-not {call[ \t]+_?_ZGIW3Foo} { target i?86-*-* x86_64-*-* } } }
// { dg-final { scan-lang-dump {Reading function definition '::frob@foo:1::member@foo:1'} module } }
-// { dg-final { scan-assembler {_ZN4frob6memberEv:} } }
+// { dg-final { scan-assembler {_ZNW3foo4frob6memberEv:} } }
export inline void Baz2 () { Foo2 (); Bink2 (); }
}
-// These fail until namespace hack is removed
-// { dg-final { scan-assembler "_ZW7linkageE3Foov:" } }
-// { dg-final { scan-assembler "_ZW7linkageE4Binkv:" } }
-// { dg-final { scan-assembler "_ZW7linkageEN5Inner4Foo2Ev:" } }
-// { dg-final { scan-assembler "_ZW7linkageEN5Inner5Bink2Ev:" } }
-// { dg-final { scan-assembler "_Z3Bazv:" } }
-// { dg-final { scan-assembler "_ZN5Inner4Baz2Ev:" } }
+// { dg-final { scan-assembler "_ZW7linkage3Foov:" } }
+// { dg-final { scan-assembler "_ZW7linkage4Binkv:" } }
+// { dg-final { scan-assembler "_ZN5InnerW7linkage4Foo2Ev:" } }
+// { dg-final { scan-assembler "_ZN5InnerW7linkage5Bink2Ev:" } }
+// { dg-final { scan-assembler "_ZW7linkage3Bazv:" } }
+// { dg-final { scan-assembler "_ZN5InnerW7linkage4Baz2Ev:" } }
// { dg-final { scan-assembler "cfunc:" } }
}
// { dg-final { scan-assembler "_Z3Foov:" } }
-// { dg-final { scan-assembler "_ZW5okely6dokelyEN3One3Two5Three4Foo2Ev:" } }
-// { dg-final { scan-assembler "_ZN3One3Two5Three4Baz2Ev:" } }
+// { dg-final { scan-assembler "_ZN3One3Two5ThreeW5okelyW6dokely4Foo2Ev:" } }
+// { dg-final { scan-assembler "_ZN3One3Two5ThreeW5okelyW6dokely4Baz2Ev:" } }
inline void X::Foo () {}
inline void X::Baz () {}
-// { dg-final { scan-assembler "_ZW3bobEN1X3FooEv:" } }
-// { dg-final { scan-assembler "_ZN1X3BazEv:" } }
-// { dg-final { scan-assembler "_ZW3bobEN1X1Y4QuuxEv:" } }
-// { dg-final { scan-assembler "_ZN1X1Y3BarEv:" } }
+// { dg-final { scan-assembler "_ZN1XW3bob3FooEv:" } }
+// { dg-final { scan-assembler "_ZN1XW3bob3BazEv:" } }
+// { dg-final { scan-assembler "_ZN1X1YW3bob4QuuxEv:" } }
+// { dg-final { scan-assembler "_ZN1X1YW3bob3BarEv:" } }
{
}
-// { dg-final { scan-assembler {_ZW3bob6stuart5kevinE4frobRW_2E6mytype:} } }
+// { dg-final { scan-assembler {_ZW3bobW6stuartW5kevin4frobRS1_6mytype:} } }
foo (m);
}
-// { dg-final { scan-assembler {_ZW3bob5kevinE3barRW_1E6mytype:} } }
-// { dg-final { scan-assembler {_ZW3bob6stuartE5innerIW_05kevinE6mytypeEvRT_:} } }
+// { dg-final { scan-assembler {_ZW3bobW5kevin3barRS0_6mytype:} } }
+// { dg-final { scan-assembler {_ZW3bobW6stuart5innerIS_W5kevin6mytypeEvRT_:} } }
export s *S;
-// { dg-final { scan-assembler {.globa?l[ \t]*_?S\n} } }
+// { dg-final { scan-assembler {.globa?l[ \t]*_?_ZW1tW1s1S\n} } }
import t.s;
struct t;
export void f (t*, decltype (S)){}
-// { dg-final { scan-assembler {_Z1fPW1tE1tPW_01sE1s:} } }
+// { dg-final { scan-assembler {_ZW1t1fPS_1tPS_W1s1s:} } }
{
}
-// { dg-final { scan-assembler {_ZW4zero4eins4zwei4drei4vier4funf5sechs6sieben4acht4neunE4frobRW_9E6mytype:} } }
+// { dg-final { scan-assembler {_ZW4zeroW4einsW4zweiW4dreiW4vierW4funfW5sechsW6siebenW4achtW4neun4frobRS8_6mytype:} } }
{
}
-// { dg-final { scan-assembler {_ZW4zero4eins4zwei4drei4vier4funf5sechs6sieben4acht4neun4zehnE4frobRWW0_E6mytype:} } }
+// { dg-final { scan-assembler {_ZW4zeroW4einsW4zweiW4dreiW4vierW4funfW5sechsW6siebenW4achtW4neunW4zehn4frobRS9_6mytype:} } }
{
}
-// { dg-final { scan-assembler {_ZW4zero4eins4zwei4drei4vier4funf5sechs6sieben4acht4neun4zehn3elfE4frobRWW1_E6mytype:} } }
+// { dg-final { scan-assembler {_ZW4zeroW4einsW4zweiW4dreiW4vierW4funfW5sechsW6siebenW4achtW4neunW4zehnW3elf4frobRSA_6mytype:} } }
// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization declaration '::foo<int>'} module } }
// { dg-final { scan-lang-dump {Pending specialization '::foo<int>' entity:[0-9]* section:. keyed to '::foo'} module } }
-// { dg-final { scan-assembler {_Z3fooIiEiT_:} } }
+// { dg-final { scan-assembler {_ZW3TPL3fooIiEiT_:} } }
// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization declaration '::foo<int>'} module } }
// { dg-final { scan-lang-dump {Pending specialization '::foo<int>' entity:[0-9]* section:. keyed to '::foo'} module } }
-// { dg-final { scan-assembler {_Z3fooIiEiT_:} } }
+// { dg-final { scan-assembler {_ZW3TPL3fooIiEiT_:} } }
// { dg-final { scan-lang-dump {Reading 1 pending entities keyed to '::foo'} module } }
// { dg-final { scan-lang-dump-not {Reading definition function_decl '::foo@TPL:.<int>'} module } }
-// { dg-final { scan-assembler-not {_Z3fooIiEiT_:} } }
-// { dg-final { scan-assembler {_Z3fooIfEiT_:} } }
+// { dg-final { scan-assembler-not {_ZW3TPL3fooIiEiT_:} } }
+// { dg-final { scan-assembler {_ZW3TPL3fooIfEiT_:} } }
// { dg-final { scan-lang-dump {Cluster members:\n \[0\]=specialization declaration '::frob::store<int>'} module } }
// { dg-final { scan-lang-dump {Pending specialization '::frob::store<int>' entity:[0-9]* section:. keyed to '::frob'} module } }
-// { dg-final { scan-assembler {_ZN4frob5storeIiEEvT_:} } }
+// { dg-final { scan-assembler {_ZNW3TPL4frob5storeIiEEvT_:} } }
return v->Visit ();
}
-// { dg-final { scan-assembler {_ZTV7Visitor:} } }
-// { dg-final { scan-assembler {_ZTI7Visitor:} } }
-// { dg-final { scan-assembler {_ZTS7Visitor:} } }
+// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZW3foo5VisitPS_7Visitor:} } }
}
// Emit here
-// { dg-final { scan-assembler {_ZTV7Visitor:} } }
-// { dg-final { scan-assembler {_ZTI7Visitor:} } }
-// { dg-final { scan-assembler {_ZTS7Visitor:} } }
+// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} } }
// We do not emit Visitor vtable
// but we do emit rtti here
-// { dg-final { scan-assembler-not {_ZTV7Visitor:} } }
-// { dg-final { scan-assembler {_ZTI7Visitor:} } }
-// { dg-final { scan-assembler {_ZTS7Visitor:} } }
+// { dg-final { scan-assembler-not {_ZTVW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} } }
// We do emit Visitor vtable
// andl also we do emit rtti here
-// { dg-final { scan-assembler {_ZTV7Visitor:} } }
-// { dg-final { scan-assembler {_ZTI7Visitor:} } }
-// { dg-final { scan-assembler {_ZTS7Visitor:} } }
+// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} } }
derived d;
}
-// { dg-final {scan-assembler "_ZTV4base:" } }
-// { dg-final {scan-assembler "_ZTV7derived:" } }
-// { dg-final {scan-assembler "_ZTT7derived:" } }
+// { dg-final {scan-assembler "_ZTVW3foo4base:" } }
+// { dg-final {scan-assembler "_ZTVW3foo7derived:" } }
+// { dg-final {scan-assembler "_ZTTW3foo7derived:" } }
mine m;
}
-// { dg-final {scan-assembler-not "_ZTV4base:" } }
-// { dg-final {scan-assembler-not "_ZTV7derived:" } }
-// { dg-final {scan-assembler-not "_ZTT7derived:" } }
-// { dg-final {scan-assembler "_ZTV4mine:" } }
-// { dg-final {scan-assembler "_ZTT4mine:" } }
+// { dg-final {scan-assembler-not "_ZTVW3foo4base:" } }
+// { dg-final {scan-assembler-not "_ZTVW3foo7derived:" } }
+// { dg-final {scan-assembler-not "_ZTTW3foo7derived:" } }
+// { dg-final {scan-assembler "_ZTVW3bar4mine:" } }
+// { dg-final {scan-assembler "_ZTTW3bar4mine:" } }