// File: /workspace/github_c_makefile_star2_O1/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 0x1f720
movl 0x10(%rbx), %ecx
leaq 0x594b4(%rip), %rdx     # 0x78bc2
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 0x1f5e0
testq %rax, %rax
je 0x1f748
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x5858d(%rip), %rsi     # 0x77cce
movq %r12, %rdx
xorl %eax, %eax
callq *(%rcx)
cmpl $0x1, (%r14)
jne 0x1f764
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x5946c(%rip), %rsi     # 0x78bc9
movq %r12, %rdx
xorl %eax, %eax
callq *(%rcx)
cmpl $0x2, (%r14)
jne 0x1f780
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x59481(%rip), %rsi     # 0x78bfa
movq %r12, %rdx
xorl %eax, %eax
callq *(%rcx)
movslq 0x10(%rbx), %rax
testq %rax, %rax
jle 0x1f7a7
movq 0x28(%rbx), %rcx
movq -0x8(%rcx,%rax,8), %rax
movq 0x108(%rax), %rcx
movl 0xc0(%rcx), %ebp
addl 0x110(%rax), %ebp
jmp 0x1f7a9
xorl %ebp, %ebp
movq %r15, %rdi
movq %r14, %rsi
callq 0x1ede7
movl %ebp, %ecx
xorl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpl %ecx, %eax
jle 0x1f7d3
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rdi
leaq 0x59448(%rip), %rsi     # 0x78c17
xorl %eax, %eax
callq *(%rcx)
movq 0x10(%r15), %rdi
movl $0x118, %esi            # imm = 0x118
callq 0xcca8
movq %rax, %r13
movl $0xff, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x3080
movb $0x0, 0xff(%r13)
movb (%r12), %cl
testb %cl, %cl
je 0x1f825
incq %r12
movl $0x1505, %eax           # imm = 0x1505
movl %eax, %edx
shll $0x5, %edx
addl %eax, %edx
movsbl %cl, %eax
addl %edx, %eax
movb (%r12), %cl
incq %r12
testb %cl, %cl
jne 0x1f80c
jmp 0x1f82a
movl $0x1505, %eax           # imm = 0x1505
movl %eax, 0x100(%r13)
movq %r14, 0x108(%r13)
movslq %ebp, %r12
movq %r15, %rdi
movq %r14, %rsi
callq 0x1ee50
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 0x1f87f
movq 0x28(%rbx), %rsi
leaq 0x8(,%rax,8), %rdx
callq 0xce23
jmp 0x1f889
movl $0x8, %esi
callq 0xcca8
movq %rax, 0x28(%rbx)
movslq 0x10(%rbx), %rax
leal 0x1(%rax), %ecx
movl %ecx, 0x10(%rbx)
movq 0x28(%rbx), %rcx
movq %r13, (%rcx,%rax,8)
movl 0xc4(%r14), %eax
cmpl %eax, 0xc4(%rbx)
jge 0x1f8b4
movl %eax, 0xc4(%rbx)
movslq 0x110(%r13), %rax
movslq 0xc0(%r14), %rcx
addq %rax, %rcx
movslq 0xc4(%rbx), %rsi
addq %rsi, %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