is only used if conflicting types are found in that compilation unit: they
will instead be placed in the child dict named TO. Many FROMs can map to one
TO: all the types are placed together in that dict, with any whose names
- collide as a result being marked as non-root types. */
+ collide as a result being marked as non-root types.
+
+ The TO mapping named "" is special: types in this are merged directly and
+ unconditionally into the shared parent dict, and are hidden (marked
+ conflicting) if they clash, rather than being moved into child dicts. */
extern int ctf_link_add_cu_mapping (ctf_dict_t *, const char *from,
const char *to);
int cu_mapped = *(int *)arg;
int isroot;
int is_conflicting;
+ int mark_type_conflicting = 0;
ctf_next_t *i = NULL;
ctf_id_t new_type;
depth, hval, ctf_link_input_name (input));
/* Conflicting types go into a per-CU output dictionary, unless this is a
- CU-mapped run. The import is not refcounted, since it goes into the
- ctf_link_outputs dict of the output that is its parent. */
+ CU-mapped run or the input CU name is empty. The import is not refcounted,
+ since it goes into the ctf_link_outputs dict of the output that is its
+ parent. */
is_conflicting = ctf_dynset_exists (d->cd_conflicting_types, hval, NULL);
- if (is_conflicting && !cu_mapped)
+ if (is_conflicting && !cu_mapped
+ && (ctf_cuname (input) == NULL ||
+ strcmp (ctf_cuname (input), "") != 0))
{
ctf_dprintf ("%i: Type %s in %i/%lx is conflicted: "
"inserting into per-CU target.\n",
name already exists and is not a forward, or if this type is hidden on the
input. */
if (cu_mapped && is_conflicting)
- isroot = 0;
+ {
+ mark_type_conflicting = 1;
+ isroot = 0;
+ }
else if (name
&& (maybe_dup = ctf_lookup_by_rawname (target, kind, name)) != 0)
{
"target %p (%s)\n", depth, hval, input_num, type, new_type,
(void *) target, ctf_link_input_name (target));
+ /* If this type is meant to be marked conflicting in this dict rather than
+ moved into a child, mark it, and note which CU it came from. */
+ if (new_type != 0 && mark_type_conflicting)
+ if (ctf_set_conflicting (target, new_type, ctf_cuname (input)) < 0)
+ goto err_target;
+
return 0;
oom_hash:
We forcibly add a dict named TO in every case, even though it may well
wind up empty, because clients that use this facility usually expect to find
- every TO dict present, even if empty, and malfunction otherwise. */
+ every TO dict present, even if empty, and malfunction otherwise.
+
+ The TO mapping named "" is special: types in this are merged directly and
+ unconditionally into the shared parent dict, and are hidden (marked conflicting) if
+ they clash, rather than being moved into child dicts. */
int
ctf_link_add_cu_mapping (ctf_dict_t *fp, const char *from, const char *to)