#include "irgen/IRGen.h" #include #include "SysYParser.h" #include "ir/IR.h" #include "utils/Log.h" namespace { void VerifyFunctionStructure(const ir::Function& func) { // 当前 IRGen 仍是单入口、顺序生成;这里在生成结束后补一层块终结校验。 for (const auto& bb : func.GetBlocks()) { if (!bb || !bb->HasTerminator()) { throw std::runtime_error( FormatError("irgen", "基本块未正确终结: " + (bb ? bb->GetName() : std::string("")))); } } } } // namespace IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema) : module_(module), sema_(sema), func_(nullptr), builder_(module.GetContext(), nullptr) {} // 编译单元的 IR 生成当前只实现了最小功能: // - Module 已在 GenerateIR 中创建,这里只负责继续生成其中的内容; // - 当前会读取编译单元中的函数定义,并交给 visitFuncDef 生成函数 IR; // // 当前还没有实现: // - 多个函数定义的遍历与生成; // - 全局变量、全局常量的 IR 生成。 std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) { if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少编译单元")); } auto* func = ctx->funcDef(); if (!func) { throw std::runtime_error(FormatError("irgen", "缺少函数定义")); } func->accept(this); return {}; } // 函数 IR 生成当前实现了: // 1. 获取函数名; // 2. 检查函数返回类型; // 3. 在 Module 中创建 Function; // 4. 将 builder 插入点设置到入口基本块; // 5. 继续生成函数体。 // // 当前还没有实现: // - 通用函数返回类型处理; // - 形参列表遍历与参数类型收集; // - FunctionType 这样的函数类型对象; // - Argument/形式参数 IR 对象; // - 入口块中的参数初始化逻辑。 // ... // 因此这里目前只支持最小的“无参 int 函数”生成。 std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) { if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少函数定义")); } if (!ctx->blockStmt()) { throw std::runtime_error(FormatError("irgen", "函数体为空")); } if (!ctx->ID()) { throw std::runtime_error(FormatError("irgen", "缺少函数名")); } if (!ctx->funcType() || !ctx->funcType()->INT()) { throw std::runtime_error(FormatError("irgen", "当前仅支持无参 int 函数")); } func_ = module_.CreateFunction(ctx->ID()->getText(), ir::Type::GetInt32Type()); builder_.SetInsertPoint(func_->GetEntry()); storage_map_.clear(); ctx->blockStmt()->accept(this); // 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。 VerifyFunctionStructure(*func_); return {}; }