Affix
view release on metacpan or search on metacpan
infix/src/core/signature.c view on Meta::CPAN
case INFIX_TYPE_STRUCT:
case INFIX_TYPE_UNION:
if (type->name) {
// Check for namespaced type (e.g. "Namespace::Class")
// Itanium mangling for namespaces is N...E
const char * p = type->name;
int parts = 0;
// Count parts
while (*p) {
if (p[0] == ':' && p[1] == ':') {
parts++;
p += 2;
}
else {
p++;
}
}
parts++; // Last part
if (parts > 1) {
_print(state, "N");
p = type->name;
while (*p) {
const char * end = strstr(p, "::");
size_t part_len = end ? (size_t)(end - p) : strlen(p);
_print(state, "%zu", part_len);
// Print part_len chars
for (size_t i = 0; i < part_len; i++)
_print(state, "%c", p[i]);
if (end)
p = end + 2;
else
break;
}
_print(state, "E");
}
else {
// Simple name
size_t len = strlen(type->name);
_print(state, "%zu%s", len, type->name);
}
_add_itanium_sub(state, type);
}
else {
// Mangling for anonymous structs isn't standardized.
// Emitting 'void' as a safe placeholder for "unknown type".
_print(state, "v");
}
break;
case INFIX_TYPE_COMPLEX:
_print(state, "C");
_infix_type_print_itanium_recursive(state, type->meta.complex_info.base_type);
_add_itanium_sub(state, type);
break;
case INFIX_TYPE_VECTOR:
_print(state, "Dv%zu_", type->size / type->meta.vector_info.element_type->size);
_infix_type_print_itanium_recursive(state, type->meta.vector_info.element_type);
_add_itanium_sub(state, type);
break;
default:
// Fallback for types that don't map cleanly to Itanium mangling
_print(state, "v");
break;
}
}
/**
* @internal
* @brief Recursively prints the MSVC C++ mangling for a type.
* @param state The printer state.
* @param type The type to mangle.
*/
static void _infix_type_print_msvc_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;
}
// Check for type back-references (0-9)
// MSVC only back-references complex types or pointers to them.
bool can_backref =
(type->category == INFIX_TYPE_POINTER || type->category == INFIX_TYPE_STRUCT ||
type->category == INFIX_TYPE_UNION || type->category == INFIX_TYPE_ENUM || type->name != nullptr);
if (can_backref) {
for (size_t i = 0; i < state->msvc_type_count; i++) {
if (state->msvc_types[i] == type) {
_print(state, "%zu", i);
return;
}
}
}
// Handle named types (Struct/Union/Enum or aliases)
if (type->name) {
// MSVC encoding:
// U = Struct
// T = Union
// W = Enum
char prefix = 'U';
if (type->category == INFIX_TYPE_UNION)
prefix = 'T';
else if (type->category == INFIX_TYPE_ENUM)
prefix = 'W';
// Check for namespaces (e.g. "Namespace::Class")
// MSVC format: <Prefix><Name>@<Namespace>@@
// Reverse order of namespaces!
if (strstr(type->name, "::")) {
_print(state, "%c", prefix);
// We need to split and reverse. Since we can't allocate easily here,
// we'll scan the string multiple times or use recursion.
// Let's use a simple stack-based approach for small depth.
const char * parts[MAX_RECURSION_DEPTH];
size_t lens[MAX_RECURSION_DEPTH];
int count = 0;
const char * p = type->name;
while (*p && count < MAX_RECURSION_DEPTH) {
parts[count] = p;
( run in 3.374 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )