Affix
view release on metacpan or search on metacpan
infix/src/core/signature.c view on Meta::CPAN
state->p += written;
state->remaining -= written;
}
}
// Forward declaration for mutual recursion in printers.
static void _infix_type_print_signature_recursive(printer_state * state, const infix_type * type);
static void _infix_type_print_itanium_recursive(printer_state * state, const infix_type * type);
static void _infix_type_print_msvc_recursive(printer_state * state, const infix_type * type);
// Itanium Mangling Helpers
static bool _find_itanium_sub(printer_state * state, const void * component, size_t * index) {
for (size_t i = 0; i < state->itanium_sub_count; i++) {
if (state->itanium_subs[i] == component) {
*index = i;
return true;
}
}
return false;
}
static void _add_itanium_sub(printer_state * state, const void * component) {
if (state->itanium_sub_count < 64)
state->itanium_subs[state->itanium_sub_count++] = component;
}
static void _print_itanium_sub(printer_state * state, size_t index) {
if (index == 0) {
_print(state, "S_");
}
else {
index--; // S0_ is index 1
_print(state, "S");
if (index == 0) {
_print(state, "0");
}
else {
char buf[16];
int pos = 0;
size_t val = index;
while (val > 0) {
int digit = val % 36;
buf[pos++] = (digit < 10) ? (char)('0' + digit) : (char)('A' + digit - 10);
val /= 36;
}
while (pos > 0)
_print(state, "%c", buf[--pos]);
}
_print(state, "_");
}
}
/**
* @internal
* @brief The internal implementation of the type-to-string printer for standard signatures.
*
* This function recursively walks a type graph and prints its signature representation.
* The key feature is the initial check for `type->name`. If a semantic alias exists,
* it is always preferred, ensuring that introspection and serialization produce
* canonical, readable output (e.g., printing "@MyHandle" instead of "*void").
*
* @param[in,out] state The printer state, which is updated as the string is built.
* @param[in] type The `infix_type` to print.
*/
static void _infix_type_print_signature_recursive(printer_state * state, const infix_type * type) {
if (state->status != INFIX_SUCCESS || !type) {
if (state->status == INFIX_SUCCESS)
state->status = INFIX_ERROR_INVALID_ARGUMENT;
return;
}
// If the type has a semantic name, always prefer printing it.
if (type->name) {
_print(state, "@%s", type->name);
return;
}
switch (type->category) {
case INFIX_TYPE_VOID:
_print(state, "void");
break;
case INFIX_TYPE_NAMED_REFERENCE:
// This case should ideally not be hit with a fully resolved type, but we handle it for robustness.
_print(state, "@%s", type->meta.named_reference.name);
break;
case INFIX_TYPE_POINTER:
_print(state, "*");
// Special handling for `void*` or recursive pointers to avoid infinite recursion.
if (type->meta.pointer_info.pointee_type == type || type->meta.pointer_info.pointee_type == nullptr ||
type->meta.pointer_info.pointee_type->category == INFIX_TYPE_VOID)
_print(state, "void");
else
_infix_type_print_signature_recursive(state, type->meta.pointer_info.pointee_type);
break;
case INFIX_TYPE_ARRAY:
if (type->meta.array_info.is_flexible)
_print(state, "[?:");
else
_print(state, "[%zu:", type->meta.array_info.num_elements);
_infix_type_print_signature_recursive(state, type->meta.array_info.element_type);
_print(state, "]");
break;
case INFIX_TYPE_STRUCT:
if (type->meta.aggregate_info.is_packed) {
_print(state, "!");
if (type->alignment != 1)
_print(state, "%zu:", type->alignment);
}
_print(state, "{");
for (size_t i = 0; i < type->meta.aggregate_info.num_members; ++i) {
if (i > 0)
_print(state, ",");
const infix_struct_member * member = &type->meta.aggregate_info.members[i];
if (member->name)
_print(state, "%s:", member->name);
_infix_type_print_signature_recursive(state, member->type);
if (member->bit_width > 0)
_print(state, ":%u", member->bit_width);
}
_print(state, "}");
break;
case INFIX_TYPE_UNION:
_print(state, "<");
for (size_t i = 0; i < type->meta.aggregate_info.num_members; ++i) {
( run in 0.676 second using v1.01-cache-2.11-cpan-ceb78f64989 )