// File: /workspace/github_c_makefile_star2_O0/pocari[P]compilerbook-9cc/type.c
// Function: add_type
void add_type(Node *node) {
  if (!node || node->ty)
    return;

  assert(node);
  add_type(node->lhs);
  add_type(node->rhs);
  add_type(node->cond);
  add_type(node->then);
  add_type(node->els);
  add_type(node->init);
  add_type(node->inc);

  for (Node *n = node->body; n; n = n->next) {
    add_type(n);
  }
  for (Node *n = node->arg; n; n = n->next) {
    add_type(n);
  }
  #pragma clang diagnostic ignored "-Wswitch"
  switch (node->kind) {
    case ND_ADD:
    case ND_SUB:
    case ND_PTR_DIFF:
    case ND_MUL:
    case ND_DIV:
    case ND_EQL:
    case ND_NOT_EQL:
    case ND_LT:
    case ND_LTE:
    case ND_BIT_AND:
    case ND_BIT_OR:
    case ND_BIT_XOR:
    case ND_A_LSHIFT:
    case ND_A_RSHIFT:
    case ND_NUM:
      node->ty = long_type;
      return;
    case ND_PTR_ADD:
    case ND_PTR_SUB:
    case ND_ASSIGN:
    case ND_POST_INC:
    case ND_POST_DEC:
    case ND_PRE_INC:
    case ND_PRE_DEC:
      node->ty = node->lhs->ty;
      return;
    case ND_VAR:
      node->ty = node->var->type;
      return;
    case ND_MEMBER:
      node->ty = node->member->ty;
      return;
    case ND_TERNARY:
      node->ty = node->then->ty;
      return;
    case ND_ADDR:
      if (node->lhs->ty->kind == TY_ARRAY) {
        node->ty = pointer_to(node->lhs->ty->ptr_to);
      } else {
        node->ty = pointer_to(node->lhs->ty);
      }
      return;
    case ND_DEREF:
      {
        if (!node->lhs->ty->ptr_to) {
          error_at(node->tok->str, "invalid pointer dereferrence");
        }
        Type *ty = node->lhs->ty->ptr_to;
        if (ty->kind == TY_VOID) {
          error_at(node->tok->str, "void *ポインタをデリファレンスできません");
        }
        if (ty->kind == TY_STRUCT && ty->is_incomplete) {
          error_at(node->tok->str, "不完全な構造体のデリファレンスはできません");
        }
        node->ty = ty;
      }
      return;
  }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0xdb9e
movq -0x8(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0xdba3
jmp 0xde10
cmpq $0x0, -0x8(%rbp)
je 0xdbac
jmp 0xdbcb
leaq 0x172d(%rip), %rdi      # 0xf2e0
leaq 0x34c6(%rip), %rsi      # 0x11080
movl $0x43, %edx
leaq 0x34c1(%rip), %rcx      # 0x11087
callq 0x20b0
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xdb80
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xdb80
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0xdb80
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rdi
callq 0xdb80
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rdi
callq 0xdb80
movq -0x8(%rbp), %rax
movq 0x58(%rax), %rdi
callq 0xdb80
movq -0x8(%rbp), %rax
movq 0x60(%rax), %rdi
callq 0xdb80
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0xdc50
movq -0x10(%rbp), %rdi
callq 0xdb80
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x10(%rbp)
jmp 0xdc32
movq -0x8(%rbp), %rax
movq 0x70(%rax), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0xdc7a
movq -0x18(%rbp), %rdi
callq 0xdb80
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0xdc5c
movq -0x8(%rbp), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x28(%rbp)
subl $0x2f, %eax
ja 0xde10
movq -0x28(%rbp), %rax
leaq 0x3324(%rip), %rcx      # 0x10fc0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x7874(%rip), %rcx      # 0x15520
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0xde10
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0xde10
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq (%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0xde10
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0xde10
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq 0x10(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0xde10
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rax
cmpl $0x8, (%rax)
jne 0xdd52
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rdi
callq 0xd990
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0xdd6e
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rdi
callq 0xd990
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0xde10
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rax
cmpq $0x0, 0x10(%rax)
jne 0xdda0
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdi
leaq 0x3304(%rip), %rsi      # 0x1109d
movb $0x0, %al
callq 0x6370
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
jne 0xddd7
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdi
leaq 0x32ea(%rip), %rsi      # 0x110ba
movb $0x0, %al
callq 0x6370
movq -0x20(%rbp), %rax
cmpl $0x9, (%rax)
jne 0xde04
movq -0x20(%rbp), %rax
testb $0x1, 0xc(%rax)
je 0xde04
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdi
leaq 0x32f7(%rip), %rsi      # 0x110f4
movb $0x0, %al
callq 0x6370
movq -0x20(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)