我先快速读取当前 IRGen 的入口与表达式/语句文件，然后按“节点到接口调用映射”给你一份可以直接交给 IRGen 同学实现的调用说明。

Read [](file:///home/shrink/nudt-compiler-cpp/include/ir/IR.h#320-320), lines 320 to 387

Read [](file:///home/shrink/nudt-compiler-cpp/include/irgen/IRGen.h)

Read [](file:///home/shrink/nudt-compiler-cpp/src/irgen/IRGenExp.cpp)

Read [](file:///home/shrink/nudt-compiler-cpp/src/irgen/IRGenStmt.cpp)

Read [](file:///home/shrink/nudt-compiler-cpp/src/irgen/IRGenFunc.cpp)

可以，下面给你一份面向 IRGen 同学的“如何调用你新增 IR 接口”的实现说明，按落地顺序写。

先看调用边界

1. IRGen 只负责把语法树翻译成 IR，不做符号查找  
变量和函数绑定依赖 Sema 结果，参考 IRGenExp.cpp 的变量读取流程。  
2. 所有指令创建都通过 IRBuilder  
新增接口定义在 IR.h。  
3. 终结指令规则必须遵守  
Ret/Br/CondBr 一旦插入当前块，这个块不能再插普通指令，规则在 Instruction.cpp 和 BasicBlock.cpp。

建议 IRGen 调用映射

一、表达式层

1. 加减乘除模
- a + b: CreateAdd(lhs, rhs, temp)
- a - b: CreateSub(lhs, rhs, temp)
- a * b: CreateMul(lhs, rhs, temp)
- a / b: CreateDiv(lhs, rhs, temp)
- a % b: CreateMod(lhs, rhs, temp)

2. 比较表达式
- == != < <= > >= 统一走 CreateCmp(op, lhs, rhs, temp)
- 返回 i32，约定 0 为假，非 0 为真

3. 一元运算建议
- -x: CreateSub(const0, x, temp)
- !x: CreateCmp(Eq, x, const0, temp)
- +x: 直接返回 x

4. 变量读取和赋值
- 读取: 先由 Sema 绑定 use 到 decl，再从 storage_map 找槽位，CreateLoad
- 赋值: EvalExpr(rhs) 后对槽位 CreateStore(rhs_val, slot)

对应修改文件：
- IRGenExp.cpp
- IRGenDecl.cpp
- IRGenStmt.cpp

二、控制流层

1. if/else
- 创建三个块: then, else, merge
- cond = EvalExpr(condExp)
- 当前块插 CreateCondBr(cond, then, else)
- 切入 then 块生成语句，末尾若未终结则 CreateBr(merge)
- 切入 else 块同理
- 最后 SetInsertPoint(merge)

2. while
- 创建三个块: cond, body, exit
- 进入前先 CreateBr(cond)
- cond 块计算条件，CreateCondBr(cond_val, body, exit)
- body 块生成循环体，若未终结则回跳 CreateBr(cond)
- 最后 SetInsertPoint(exit)

3. break/continue
- IRGen 维护循环栈，每层保存 continue_target 和 break_target
- break 直接 CreateBr(break_target)
- continue 直接 CreateBr(continue_target)

对应修改文件：
- IRGenStmt.cpp

三、函数与调用层

1. 函数定义
- 用 Module.CreateFunction(name, ret_type, param_types) 建函数
- 入口块 SetInsertPoint(entry)
- 形参落栈策略建议：每个参数先 alloca，再 store 到本地槽位，后续统一按 load/store 访问

2. 函数调用
- 先拿到 callee 对应的 Function
- 实参逐个 EvalExpr 得到 args
- 调用 CreateCall(callee, args, temp)
- 若返回值非 void，把返回 Value 继续参与表达式计算

对应修改文件：
- IRGenFunc.cpp
- IRGenExp.cpp

四、你要提醒 IRGen 同学的两个关键点

1. 插入点管理  
每次生成 Br/CondBr/Ret 后，必须切换到新块再继续生成。否则会触发块已终结错误。  
2. grammar 上下文名先对齐  
你们当前 IRGen 里还在用 ParenExpContext、AdditiveExpContext 这类命名，实际 grammar 是另一套层级时要先改 Visitor 入口，否则接口再全也接不上。可先核对 SysY.g4 与 IRGen.h。

最小接入顺序

1. 先接表达式算术与比较（M1）  
2. 再接 if/while/break/continue（M3）  
3. 再接函数参数和调用（M2）

如果你要，我下一步可以给你一版“按当前 grammar 的具体 visitor 函数名”逐条对照表，IRGen 同学可以直接照着改函数签名和调用点。