extern int ctf_type_kind_forwarded (ctf_dict_t *, ctf_id_t);
+/* Return nonzero if this type is conflicting, zero if it's not, < 0 on error; if
+ CUNAME is set, set it to the name of the conflicting compilation unit for the
+ passed-in type (which may be a null string if the cuname is not known, or if
+ this is not a conflicting type). */
+
+extern int ctf_type_conflicting (ctf_dict_t *, ctf_id_t, const char **cuname);
+
/* Return the type a pointer, typedef, cvr-qual, or slice refers to, or return
an ECTF_NOTREF error otherwise. ctf_type_kind pretends that slices are
actually the type they are a slice of: this is usually want you want, but if
extern int ctf_set_array (ctf_dict_t *, ctf_id_t, const ctf_arinfo_t *);
-/* Add a function oor object symbol type with a particular name, without saying
+/* Mark a type as conflicting, residing in some other translation unit with a
+ given name. The type is hidden from all name lookups, just like
+ CTF_ADD_NONROOT. */
+
+extern int ctf_set_conflicting (ctf_dict_t *, ctf_id_t, const char *);
+
+/* Add a function or object symbol type with a particular name, without saying
anything about the actual symbol index. (The linker will then associate them
with actual symbol indexes using the ctf_link functions below.) */
return 0;
}
+/* Set this type as conflicting in compilation unit CUNAME. */
+int
+ctf_set_conflicting (ctf_dict_t *fp, ctf_id_t type, const char *cuname)
+{
+ ctf_dict_t *ofp = fp;
+ ctf_dtdef_t *dtd;
+ ctf_type_t *prefix;
+ uint32_t idx;
+
+ if (ctf_lookup_by_id (&fp, type, NULL) == NULL)
+ return -1; /* errno is set for us. */
+
+ idx = ctf_type_to_index (fp, type);
+ dtd = ctf_dtd_lookup (fp, type);
+
+ /* You can only call ctf_set_conflicting on a type you have added, not a type
+ that was read in via ctf_open. */
+ if (idx < fp->ctf_stypes)
+ return (ctf_set_errno (ofp, ECTF_RDONLY));
+
+ if (dtd == NULL)
+ return (ctf_set_errno (ofp, ECTF_BADID));
+
+ if ((prefix = (ctf_type_t *) ctf_find_prefix (fp, dtd->dtd_buf,
+ CTF_K_CONFLICTING)) == NULL)
+ {
+ if ((prefix = ctf_add_prefix (fp, dtd, 0)) == NULL)
+ return -1; /* errno is set for us. */
+ }
+ prefix->ctt_name = ctf_str_add (fp, cuname);
+ prefix->ctt_info = CTF_TYPE_INFO (CTF_K_CONFLICTING, 0,
+ dtd->dtd_vlen_size < 65536
+ ? dtd->dtd_vlen_size : 0);
+
+ return 0;
+}
+
/* Add a type or decl tag applying to some whole type, or to some
component of a type. Component -1 is a whole type. */
return ret;
}
+/* Return nonzero if this type is conflicting, nonzero if it's not, < 0 on
+ error; if CUNAME is set, set it to the name of the conflicting compilation
+ unit for the passed-in type (which may be a null string if the cuname is not
+ known). */
+
+int
+ctf_type_conflicting (ctf_dict_t *fp, ctf_id_t type, const char **cuname)
+{
+ ctf_dict_t *ofp = fp;
+ const ctf_type_t *tp;
+
+ /* The unimplemented / void type is never conflicting. */
+ if (type == 0)
+ return 0;
+
+ if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
+ return -1; /* errno is set for us. */
+
+ if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL)
+ return -1; /* errno is set for us. */
+
+ if (cuname)
+ *cuname = 0;
+
+ if (LCTF_INFO_ISROOT (fp, tp->ctt_info))
+ return 0;
+
+ if (!cuname)
+ return 1;
+
+ while (LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info) != CTF_K_CONFLICTING
+ && LCTF_IS_PREFIXED_INFO (tp->ctt_info))
+ tp++;
+
+ /* We already checked that this is a non-root-visible type, so this must be
+ CTF_K_CONFLICTING. */
+ if (!ctf_assert (ofp, LCTF_IS_PREFIXED_INFO (tp->ctt_info)))
+ return -1; /* errno is set for us. */
+
+ *cuname = ctf_strptr (fp, tp->ctt_name);
+ return 1;
+}
+
/* If the type is one that directly references another type (such as POINTER),
then return the ID of the type to which it refers. */
ctf_type_align;
ctf_type_kind;
ctf_type_kind_forwarded;
+ ctf_type_conflicting;
ctf_type_reference;
ctf_type_linkage;
ctf_type_pointer;
ctf_add_member_bitfield;
ctf_set_array;
+ ctf_set_conflicting;
ctf_update;
ctf_discard;