#include "irgen/IRGen.h" #include #include #include #include "SysYParser.h" #include "ir/IR.h" #include "utils/Log.h" namespace { void VerifyFunctionStructure(const ir::Function& func) { 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) {} // 修正:没有 mainFuncDef,通过函数名找到 main std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) { std::cout << "[DEBUG IRGEN] visitCompUnit" << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少编译单元")); } // 处理全局变量声明 for (auto* decl : ctx->decl()) { if (decl) { decl->accept(this); } } // 处理所有函数定义 for (auto* funcDef : ctx->funcDef()) { if (funcDef) { funcDef->accept(this); } } return {}; } std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) { std::cout << "[DEBUG IRGEN] visitFuncDef: " << (ctx && ctx->Ident() ? ctx->Ident()->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少函数定义")); } if (!ctx->Ident()) { throw std::runtime_error(FormatError("irgen", "缺少函数名")); } std::string funcName = ctx->Ident()->getText(); if (!ctx->block()) { throw std::runtime_error(FormatError("irgen", "函数体为空")); } std::shared_ptr ret_type = ir::Type::GetInt32Type(); if (ctx->funcType()) { if (ctx->funcType()->Void()) { ret_type = ir::Type::GetVoidType(); } else if (ctx->funcType()->Int()) { ret_type = ir::Type::GetInt32Type(); } else if (ctx->funcType()->Float()) { ret_type = ir::Type::GetFloatType(); } } std::vector> param_types; if (ctx->funcFParams()) { for (auto* param : ctx->funcFParams()->funcFParam()) { if (!param || !param->bType()) continue; std::shared_ptr param_ty; if (param->bType()->Int()) { param_ty = ir::Type::GetInt32Type(); } else if (param->bType()->Float()) { param_ty = ir::Type::GetFloatType(); } else { param_ty = ir::Type::GetInt32Type(); } if (!param->L_BRACK().empty()) { if (param_ty->IsInt32()) { param_ty = ir::Type::GetPtrInt32Type(); } else if (param_ty->IsFloat()) { param_ty = ir::Type::GetPtrFloatType(); } } param_types.push_back(param_ty); } } auto func_type = ir::Type::GetFunctionType(ret_type, param_types); func_ = module_.CreateFunction(funcName, func_type); builder_.SetInsertPoint(func_->GetEntry()); storage_map_.clear(); param_map_.clear(); // 函数参数 (按照语义分析、symbol table 定义顺序) if (ctx->funcFParams()) { for (auto* param : ctx->funcFParams()->funcFParam()) { if (!param || !param->Ident()) continue; std::string name = param->Ident()->getText(); std::shared_ptr param_ty; if (param->bType()->Int()) { param_ty = ir::Type::GetInt32Type(); } else if (param->bType()->Float()) { param_ty = ir::Type::GetFloatType(); } else { param_ty = ir::Type::GetInt32Type(); } if (!param->L_BRACK().empty()) { if (param_ty->IsInt32()) { param_ty = ir::Type::GetPtrInt32Type(); } else if (param_ty->IsFloat()) { param_ty = ir::Type::GetPtrFloatType(); } } auto* arg = func_->AddArgument(std::make_unique(param_ty, name)); ir::AllocaInst* slot; if (param_ty->IsInt32() || param_ty->IsPtrInt32()) { slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp()); } else if (param_ty->IsFloat() || param_ty->IsPtrFloat()) { slot = builder_.CreateAllocaFloat(module_.GetContext().NextTemp()); } else { throw std::runtime_error(FormatError("irgen", "不支持的参数类型")); } builder_.CreateStore(arg, slot); param_map_[name] = slot; } } // 生成函数体 ctx->block()->accept(this); if (!func_->GetEntry()->HasTerminator()) { auto retVal = builder_.CreateConstInt(0); builder_.CreateRet(retVal); } VerifyFunctionStructure(*func_); func_ = nullptr; return {}; } std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) { std::cout << "[DEBUG IRGEN] visitBlock: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少语句块")); } BlockFlow flow = BlockFlow::Continue; for (auto* item : ctx->blockItem()) { if (!item) continue; flow = VisitBlockItemResult(*item); if (flow == BlockFlow::Terminated) { break; } auto* cur = builder_.GetInsertBlock(); std::cout << "[DEBUG] current insert block: " << (cur ? cur->GetName() : "") << std::endl; if (cur && cur->HasTerminator()) { break; } } return flow; } // 类型安全的包装器 IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult( SysYParser::BlockItemContext& item) { auto result = item.accept(this);// 调用 visitBlockItem,返回 std::any 包装的 BlockFlow return std::any_cast(result); // 解包为 BlockFlow } // 用于遍历块内项,返回是否继续访问后续项(如遇到 return/break/continue 则终止访问) std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) { std::cout << "[DEBUG IRGEN] visitBlockItem: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少块内项")); } // 块内项可以是语句或声明,优先处理语句(如 return/break/continue 可能终止块内执行) if (ctx->stmt()) { return ctx->stmt()->accept(this); // 语句访问返回 BlockFlow,指示是否继续访问后续项 } // 处理声明(如变量定义),继续访问后续项 if (ctx->decl()) { ctx->decl()->accept(this); return BlockFlow::Continue; // 声明不会终止块内执行,继续访问后续项 } throw std::runtime_error(FormatError("irgen", "暂不支持的块内项")); }