// File: /workspace/github_c_makefile_star2_O2/vtereshkov[P]umka-lang/src/umka_types.c
// Function: typeAddField
const Field *typeAddField(const Types *types, Type *structType, const Type *fieldType, const char *fieldName)
{
    IdentName fieldNameBuf;
    const char *name;

    if (fieldName)
        name = fieldName;
    else
    {
        // Automatic field naming
        snprintf(fieldNameBuf, DEFAULT_STR_LEN + 1, "item%d", structType->numItems);
        name = fieldNameBuf;
    }

    if (typeFindField(structType, name, NULL))
        types->error->handler(types->error->context, "Duplicate field %s", name);

    if (fieldType->kind == TYPE_FORWARD)
        types->error->handler(types->error->context, "Unresolved forward type declaration for field %s", name);

    if (fieldType->kind == TYPE_VOID)
        types->error->handler(types->error->context, "Void field %s is not allowed", name);

    int minNextFieldOffset = 0;
    if (structType->numItems > 0)
    {
        const Field *lastField = structType->field[structType->numItems - 1];
        minNextFieldOffset = lastField->offset + lastField->type->size;
    }

    if (typeSize(types, fieldType) > INT_MAX - minNextFieldOffset)
        types->error->handler(types->error->context, "Structure is too large");

    Field *field = storageAdd(types->storage, sizeof(Field));

    strncpy(field->name, name, MAX_IDENT_LEN);
    field->name[MAX_IDENT_LEN] = 0;

    field->hash = hash(name);
    field->type = fieldType;
    field->offset = align(minNextFieldOffset, typeAlignment(types, fieldType));

    if (structType->numItems > 0)
        structType->field = storageRealloc(types->storage, structType->field, (structType->numItems + 1) * sizeof(Field *));
    else
        structType->field = storageAdd(types->storage, sizeof(Field *));

    structType->numItems++;
    structType->field[structType->numItems - 1] = field;

    if (structType->alignment < fieldType->alignment)
        structType->alignment = fieldType->alignment;

    structType->size = align(field->offset + fieldType->size, structType->alignment);

    return field;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movq %rcx, %r12
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r15
testq %rcx, %rcx
jne 0x15a2e
movl 0x10(%rbx), %ecx
leaq 0x56186(%rip), %rdx     # 0x6bba2
movq %rsp, %r12
movl $0x100, %esi            # imm = 0x100
movq %r12, %rdi
xorl %eax, %eax
callq 0x3170
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x1590a
testq %rax, %rax
je 0x15a56
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x55223(%rip), %rsi     # 0x6ac72
movq %r12, %rdx
xorl %eax, %eax
callq *(%rcx)
movl (%r14), %eax
cmpl $0x1, %eax
jne 0x15a77
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x5613c(%rip), %rsi     # 0x6bba9
movq %r12, %rdx
xorl %eax, %eax
callq *(%rcx)
movl (%r14), %eax
cmpl $0x2, %eax
jne 0x15a92
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x5614f(%rip), %rsi     # 0x6bbda
movq %r12, %rdx
xorl %eax, %eax
callq *(%rcx)
movslq 0x10(%rbx), %rax
testq %rax, %rax
jle 0x15ab9
movq 0x28(%rbx), %rcx
movq -0x8(%rcx,%rax,8), %rax
movq 0x108(%rax), %rcx
movl 0xc0(%rcx), %ebp
addl 0x110(%rax), %ebp
jmp 0x15abb
xorl %ebp, %ebp
movq %r15, %rdi
movq %r14, %rsi
callq 0x15124
movl %ebp, %ecx
xorl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpl %ecx, %eax
jle 0x15ae5
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x56116(%rip), %rsi     # 0x6bbf7
xorl %eax, %eax
callq *(%rcx)
movq 0x10(%r15), %rdi
movl $0x118, %esi            # imm = 0x118
callq 0x4144
movq %rax, %r13
movl $0xff, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x3080
movb $0x0, 0xff(%r13)
movq %r12, %rdi
callq 0x15999
movl %eax, 0x100(%r13)
movq %r14, 0x108(%r13)
movslq %ebp, %r12
movq %r15, %rdi
movq %r14, %rsi
callq 0x15188
movslq %eax, %rsi
leaq (%r12,%rsi), %rcx
decq %rcx
movq %rcx, %rax
cqto
idivq %rsi
subl %edx, %ecx
movl %ecx, 0x110(%r13)
movl 0x10(%rbx), %eax
movq 0x10(%r15), %rdi
testl %eax, %eax
jle 0x15b6b
movq 0x28(%rbx), %rsi
leaq 0x8(,%rax,8), %rdx
callq 0x42b1
jmp 0x15b73
pushq $0x8
popq %rsi
callq 0x4144
movq %rax, 0x28(%rbx)
movslq 0x10(%rbx), %rcx
leal 0x1(%rcx), %edx
movl %edx, 0x10(%rbx)
movq %r13, (%rax,%rcx,8)
movl 0xc4(%rbx), %eax
movl 0xc4(%r14), %ecx
cmpl %ecx, %eax
jge 0x15b9e
movl %ecx, 0xc4(%rbx)
movl %ecx, %eax
movslq 0x110(%r13), %rcx
movslq 0xc0(%r14), %rdx
addq %rcx, %rdx
movslq %eax, %rsi
leaq (%rsi,%rdx), %rcx
decq %rcx
movq %rcx, %rax
cqto
idivq %rsi
subl %edx, %ecx
movl %ecx, 0xc0(%rbx)
movq %r13, %rax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq