|
|
// IRGen:语法树 → IR
|
|
|
// 按语法树节点类型分发到 IRGenFunc/IRGenStmt/IRGenExp/IRGenDecl
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
#include <any>
|
|
|
#include <memory>
|
|
|
#include <string>
|
|
|
#include <unordered_map>
|
|
|
#include <vector>
|
|
|
|
|
|
#include "SysYBaseVisitor.h"
|
|
|
#include "SysYParser.h"
|
|
|
#include "ir/IR.h"
|
|
|
#include "sem/Sema.h"
|
|
|
|
|
|
class IRGenImpl final : public SysYBaseVisitor {
|
|
|
public:
|
|
|
IRGenImpl(ir::Module& module, const SemanticContext& sema);
|
|
|
|
|
|
// ── 顶层 ──────────────────────────────────────────────────────────────────
|
|
|
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
|
|
|
|
|
|
// ── 函数 ──────────────────────────────────────────────────────────────────
|
|
|
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
|
|
|
|
|
|
// ── 块与块内项 ─────────────────────────────────────────────────────────────
|
|
|
std::any visitBlock(SysYParser::BlockContext* ctx) override;
|
|
|
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
|
|
|
|
|
|
// ── 声明 ──────────────────────────────────────────────────────────────────
|
|
|
std::any visitDecl(SysYParser::DeclContext* ctx) override;
|
|
|
std::any visitVarDecl(SysYParser::VarDeclContext* ctx) override;
|
|
|
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
|
|
|
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
|
|
|
|
|
|
// ── 语句 ──────────────────────────────────────────────────────────────────
|
|
|
std::any visitStmt(SysYParser::StmtContext* ctx) override;
|
|
|
|
|
|
// ── 表达式(返回 ir::Value*,i32) ─────────────────────────────────────────
|
|
|
std::any visitExp(SysYParser::ExpContext* ctx) override;
|
|
|
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
|
|
|
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
|
|
|
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override;
|
|
|
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
|
|
|
std::any visitLVar(SysYParser::LVarContext* ctx) override;
|
|
|
std::any visitNumber(SysYParser::NumberContext* ctx) override;
|
|
|
|
|
|
// ── 条件(返回 ir::Value*,i1) ────────────────────────────────────────────
|
|
|
std::any visitCond(SysYParser::CondContext* ctx) override;
|
|
|
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
|
|
|
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
|
|
|
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
|
|
|
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
|
|
|
|
|
|
private:
|
|
|
// BlockFlow 用于通知调用者当前块是否已终结
|
|
|
enum class BlockFlow { Continue, Terminated };
|
|
|
|
|
|
// ── 辅助函数 ──────────────────────────────────────────────────────────────
|
|
|
// 求值表达式,返回 i32 值
|
|
|
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
|
|
|
ir::Value* EvalExprAdd(SysYParser::AddExpContext& expr);
|
|
|
// 求值条件,返回 i1 值(供 if/while 使用)
|
|
|
ir::Value* EvalCond(SysYParser::CondContext& cond);
|
|
|
// 把整型值转为 i1 条件(icmp ne i32 val, 0)
|
|
|
ir::Value* ToI1(ir::Value* v);
|
|
|
// 把 i1 值零扩展为 i32
|
|
|
ir::Value* ToI32(ir::Value* v);
|
|
|
// 隐式类型转换:确保两个操作数类型一致(int 转 float)
|
|
|
void ImplicitConvert(ir::Value*& lhs, ir::Value*& rhs);
|
|
|
// 转换为 float(如果是 int)
|
|
|
ir::Value* ToFloat(ir::Value* v);
|
|
|
// 转换为 int(如果是 float)
|
|
|
ir::Value* ToInt(ir::Value* v);
|
|
|
|
|
|
// 访问一条块内项,返回流控状态
|
|
|
BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item);
|
|
|
// 访问 stmt,返回流控状态
|
|
|
BlockFlow VisitStmt(SysYParser::StmtContext& stmt);
|
|
|
|
|
|
// 向外部函数声明注册(幂等)
|
|
|
void EnsureExternalDecl(const std::string& name);
|
|
|
|
|
|
// ── 状态 ──────────────────────────────────────────────────────────────────
|
|
|
ir::Module& module_;
|
|
|
const SemanticContext& sema_;
|
|
|
ir::Function* func_ = nullptr;
|
|
|
ir::IRBuilder builder_;
|
|
|
|
|
|
// 局部变量/参数的存储槽位:声明上下文 → alloca Value*
|
|
|
std::unordered_map<antlr4::ParserRuleContext*, ir::Value*> storage_map_;
|
|
|
// 全局变量/常量的存储槽位(不随函数切换清空)
|
|
|
std::unordered_map<antlr4::ParserRuleContext*, ir::Value*> global_storage_map_;
|
|
|
|
|
|
// 数组维度信息:声明上下文 → 各维度大小(从外到内)
|
|
|
std::unordered_map<antlr4::ParserRuleContext*, std::vector<int>> array_dims_;
|
|
|
std::unordered_map<antlr4::ParserRuleContext*, std::vector<int>> global_array_dims_;
|
|
|
|
|
|
// 辅助:求常量表达式的整数值(失败返回 0)
|
|
|
int EvalConstExprInt(SysYParser::ConstExpContext* ctx);
|
|
|
// 辅助:计算一个 lVar 的元素地址(支持多维数组)
|
|
|
ir::Value* EvalLVarAddr(SysYParser::LVarContext* ctx);
|
|
|
|
|
|
// 是否处于全局作用域(visitCompUnit 中处理 decl 时)
|
|
|
bool in_global_scope_ = false;
|
|
|
|
|
|
// 循环上下文(break/continue 的目标块)
|
|
|
struct LoopCtx {
|
|
|
ir::BasicBlock* cond_bb; // continue 跳到这里
|
|
|
ir::BasicBlock* after_bb; // break 跳到这里
|
|
|
};
|
|
|
std::vector<LoopCtx> loop_stack_;
|
|
|
};
|
|
|
|
|
|
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
|
|
|
const SemanticContext& sema);
|