// File: /workspace/github_c_makefile_star2_O0/ejunjsh[P]mycc/decl.c
// Function: scalar_declaration
static struct symtable *scalar_declaration(char *varname, int type,
					   struct symtable *ctype,
					   int class, struct ASTnode **tree) {
  struct symtable *sym = NULL;
  struct ASTnode *varnode, *exprnode;
  *tree = NULL;

  // 加入到相应的符号表
  switch (class) {
    case C_STATIC:
    case C_EXTERN:
    case C_GLOBAL:
      // 检查变量是新的还是已经存在
      sym= findglob(varname);
      if (is_new_symbol(sym, class, type, ctype))
        sym = addglob(varname, type, ctype, S_VARIABLE, class, 1, 0);
      break;
    case C_LOCAL:
      sym = addlocl(varname, type, ctype, S_VARIABLE, 1);
      break;
    case C_PARAM:
      sym = addparm(varname, type, ctype, S_VARIABLE);
      break;
    case C_MEMBER:
      sym = addmemb(varname, type, ctype, S_VARIABLE, 1);
      break;
  }

  // 这个变量需要初始化
  if (Token.token == T_ASSIGN) {
    // 只能在全局或者本地
    if (class != C_GLOBAL && class != C_LOCAL && class != C_STATIC)
      fatals("Variable can not be initialised", varname);
    scan(&Token);

    // 全局只能是字面量值
    if (class == C_GLOBAL || class == C_STATIC) {
      // 为这个变量创建一个初始值，同时解析这个值
      sym->initlist = (int *) malloc(sizeof(int));
      sym->initlist[0] = parse_literal(type);
    }
    // 处理本地
    if (class == C_LOCAL) {
      // 为这个变量创建一个A_IDENT语法树节点
      varnode = mkastleaf(A_IDENT, sym->type, sym->ctype, sym, 0);

      // 获得这个赋值的表达式语法树，同时令他右值
      exprnode = binexpr(0);
      exprnode->rvalue = 1;

      // 保证表达式类型匹配这个变量
      exprnode = modify_type(exprnode, varnode->type, varnode->ctype, 0);
      if (exprnode == NULL)
	      fatal("Incompatible expression in assignment");

      // 创建一个赋值语法树
      *tree = mkastnode(A_ASSIGN, exprnode->type, exprnode->ctype, exprnode,
			NULL, varnode, NULL, 0);
    }
  }

  // 如果包含全局或静态变量定义的话，创建全局空间
  if (class == C_GLOBAL || class == C_STATIC)
    genglobsym(sym);

  return (sym);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq %r8, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x28(%rbp), %rax
movq $0x0, (%rax)
movl -0x1c(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x48(%rbp)
subl $0x7, %eax
ja 0x54c5
movq -0x48(%rbp), %rax
leaq 0x74d8(%rip), %rcx      # 0xc8f4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rdi
callq 0xa2f0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x18(%rbp), %rcx
callq 0x5750
cmpl $0x0, %eax
je 0x5471
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rdx
movl -0x1c(%rbp), %r8d
xorl %ecx, %ecx
movl $0x1, %r9d
movl $0x0, (%rsp)
callq 0x9f70
movq %rax, -0x30(%rbp)
jmp 0x54c5
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rdx
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0xa000
movq %rax, -0x30(%rbp)
jmp 0x54c5
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rdx
xorl %ecx, %ecx
callq 0xa080
movq %rax, -0x30(%rbp)
jmp 0x54c5
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rdx
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0xa0f0
movq %rax, -0x30(%rbp)
leaq 0xd064(%rip), %rax      # 0x12530
cmpl $0x1, (%rax)
jne 0x55f1
cmpl $0x1, -0x1c(%rbp)
je 0x54f7
cmpl $0x2, -0x1c(%rbp)
je 0x54f7
cmpl $0x5, -0x1c(%rbp)
je 0x54f7
movq -0x8(%rbp), %rsi
leaq 0x77c3(%rip), %rdi      # 0xccb5
callq 0x7fc0
leaq 0xd032(%rip), %rdi      # 0x12530
callq 0x84c0
cmpl $0x1, -0x1c(%rbp)
je 0x550f
cmpl $0x5, -0x1c(%rbp)
jne 0x5538
movl $0x4, %edi
callq 0x2100
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x30(%rax)
movl -0xc(%rbp), %edi
callq 0x4ae0
movl %eax, %ecx
movq -0x30(%rbp), %rax
movq 0x30(%rax), %rax
movl %ecx, (%rax)
cmpl $0x2, -0x1c(%rbp)
jne 0x55ef
movq -0x30(%rbp), %rax
movl 0x10(%rax), %esi
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rdx
movq -0x30(%rbp), %rcx
movl $0x1c, %edi
xorl %r8d, %r8d
callq 0xad50
movq %rax, -0x38(%rbp)
xorl %edi, %edi
callq 0x58c0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl $0x1, 0x18(%rax)
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rdx
xorl %ecx, %ecx
callq 0xb800
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x55ad
leaq 0x77c2(%rip), %rdi      # 0xcd6a
callq 0x8110
movq -0x40(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %r9
movl $0x1, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %eax, %eax
movq $0x0, (%rsp)
movl $0x0, 0x8(%rsp)
callq 0xac90
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x55f1
cmpl $0x1, -0x1c(%rbp)
je 0x55fd
cmpl $0x5, -0x1c(%rbp)
jne 0x5606
movq -0x30(%rbp), %rdi
callq 0x7570
movq -0x30(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq