// File: /workspace/github_c_makefile_star2_O0/ejunjsh[P]mycc/decl.c
// Function: enum_declaration
static void enum_declaration(void) {
  struct symtable *etype = NULL;
  char *name = NULL;
  int intval = 0;

  // 跳过枚举关键字
  scan(&Token);

  // 如果接下来是枚举类型名，
  // 获得一个指向存在枚举类型节点的指针
  if (Token.token == T_IDENT) {
    etype = findenumtype(Text);
    name = strdup(Text); // 拷贝出来
    scan(&Token);
  }

  // 如果下个token不是个左括号
  // 检查是否存在这个枚举类型，然后返回
  if (Token.token != T_LBRACE) {
    if (etype == NULL)
      fatals("undeclared enum type:", name);
    return;
  }

  // 跳过左括号
  scan(&Token);

  // 如果之前有声明过，报错
  if (etype != NULL)
    fatals("enum type redeclared:", etype->name);
  else
    // 创建一个枚举类型节点
    etype = addenum(name, C_ENUMTYPE, 0);

  // 循环获得所有枚举值
  while (1) {

    // 保证我们有一个标识符    
    ident();
    name = strdup(Text); // 拷贝出来

    // 保证之前枚举值没有声明过
    etype = findenumval(name);
    if (etype != NULL)
      fatals("enum value redeclared:", Text);

    // 如果下个token是'=',跳过它去获取接下来的整型字面量
    if (Token.token == T_ASSIGN) {
      scan(&Token);
      if (Token.token != T_INTLIT)
	      fatal("Expected int literal after '='");
      intval = Token.intvalue;
      scan(&Token);
    }

    // 创建一个枚举值节点
    // 为下个枚举值加一
    etype = addenum(name, C_ENUMVAL, intval++);

    // 如果是右括号，退出
    // 否则匹配逗号，然后继续
    if (Token.token == T_RBRACE)
      break;
    comma();
  }
  scan(&Token);			// 跳过右括号
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq $0x0, -0x8(%rbp)
movq $0x0, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
leaq 0xdd6a(%rip), %rdi      # 0x12530
callq 0x84c0
leaq 0xdd5e(%rip), %rax      # 0x12530
cmpl $0x36, (%rax)
jne 0x4803
leaq 0xdd82(%rip), %rdi      # 0x12560
callq 0xa540
movq %rax, -0x8(%rbp)
leaq 0xdd72(%rip), %rdi      # 0x12560
callq 0x2150
movq %rax, -0x10(%rbp)
leaq 0xdd32(%rip), %rdi      # 0x12530
callq 0x84c0
leaq 0xdd26(%rip), %rax      # 0x12530
cmpl $0x37, (%rax)
je 0x482b
cmpq $0x0, -0x8(%rbp)
jne 0x4826
movq -0x10(%rbp), %rsi
leaq 0x8280(%rip), %rdi      # 0xcaa1
callq 0x7fc0
jmp 0x4930
leaq 0xdcfe(%rip), %rdi      # 0x12530
callq 0x84c0
cmpq $0x0, -0x8(%rbp)
je 0x4854
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x826a(%rip), %rdi      # 0xcab7
callq 0x7fc0
jmp 0x4868
movq -0x10(%rbp), %rdi
movl $0x9, %esi
xorl %edx, %edx
callq 0xa230
movq %rax, -0x8(%rbp)
jmp 0x486a
callq 0x80d0
leaq 0xdcea(%rip), %rdi      # 0x12560
callq 0x2150
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0xa570
movq %rax, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x48a6
leaq 0x8233(%rip), %rdi      # 0xcacd
leaq 0xdcbf(%rip), %rsi      # 0x12560
callq 0x7fc0
leaq 0xdc83(%rip), %rax      # 0x12530
cmpl $0x1, (%rax)
jne 0x48ef
leaq 0xdc77(%rip), %rdi      # 0x12530
callq 0x84c0
leaq 0xdc6b(%rip), %rax      # 0x12530
cmpl $0x33, (%rax)
je 0x48d6
leaq 0x8213(%rip), %rdi      # 0xcae4
callq 0x8110
leaq 0xdc53(%rip), %rax      # 0x12530
movl 0x10(%rax), %eax
movl %eax, -0x14(%rbp)
leaq 0xdc46(%rip), %rdi      # 0x12530
callq 0x84c0
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %edx
movl %edx, %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl $0xa, %esi
callq 0xa230
movq %rax, -0x8(%rbp)
leaq 0xdc1d(%rip), %rax      # 0x12530
cmpl $0x38, (%rax)
jne 0x491a
jmp 0x4924
callq 0x80f0
jmp 0x486a
leaq 0xdc05(%rip), %rdi      # 0x12530
callq 0x84c0
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)