style(ir): 纠正代码位置

This commit is contained in:
jing
2026-03-11 22:08:27 +08:00
parent 62dde8d7ab
commit fab6983d40
17 changed files with 193 additions and 88 deletions

View File

@@ -9,6 +9,7 @@
#include "SysYParser.h"
#include "ir/IR.h"
#include "sem/Sema.h"
namespace antlr4 {
namespace tree {
@@ -25,7 +26,7 @@ class Value;
class IRGenImpl {
public:
explicit IRGenImpl(ir::Module& module);
IRGenImpl(ir::Module& module, const SemanticContext& sema);
void Gen(SysYParser::CompUnitContext& cu);
@@ -43,10 +44,12 @@ class IRGenImpl {
ir::Value* GenPrimary(SysYParser::PrimaryContext& primary);
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
// 当前只维护函数级局部变量表;若后续引入嵌套块作用域,需要改成作用域栈
std::unordered_map<std::string, ir::Value*> locals_;
// 名称绑定由 Sema 负责IRGen 只维护“声明 -> 存储槽位”的代码生成状态
std::unordered_map<SysYParser::VarDeclContext*, ir::Value*> storage_map_;
};
std::unique_ptr<ir::Module> GenerateIR(antlr4::tree::ParseTree* tree);
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema);

View File

@@ -36,12 +36,11 @@ void IRGenImpl::GenDecl(SysYParser::DeclContext& decl) {
}
void IRGenImpl::GenVarDecl(SysYParser::VarDeclContext& decl) {
const std::string name = decl.Ident()->getText();
if (locals_.find(name) != locals_.end()) {
throw std::runtime_error("[irgen] 重复定义变量: " + name);
if (storage_map_.find(&decl) != storage_map_.end()) {
throw std::runtime_error("[irgen] 声明重复生成存储槽位");
}
auto* slot = builder_.CreateAllocaI32(ir::DefaultContext().NextTemp());
locals_[name] = slot;
storage_map_[&decl] = slot;
ir::Value* init = nullptr;
if (decl.exp()) {

View File

@@ -4,21 +4,12 @@
#include <stdexcept>
#include "SysYParser.h"
#include "antlr4-runtime.h"
#include "ir/IR.h"
std::unique_ptr<ir::Module> GenerateIR(antlr4::tree::ParseTree* tree) {
if (!tree) {
throw std::runtime_error("[irgen] 语法树为空");
}
auto* cu = dynamic_cast<SysYParser::CompUnitContext*>(tree);
if (!cu) {
throw std::runtime_error("[irgen] 语法树根节点不是 compUnit");
}
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema) {
auto module = std::make_unique<ir::Module>();
IRGenImpl gen(*module);
gen.Gen(*cu);
IRGenImpl gen(*module, sema);
gen.Gen(tree);
return module;
}

View File

@@ -33,10 +33,15 @@ ir::Value* IRGenImpl::GenPrimary(SysYParser::PrimaryContext& primary) {
return ir::DefaultContext().GetConstInt(std::stoi(primary.Number()->getText()));
}
if (primary.Ident()) {
const std::string name = primary.Ident()->getText();
auto it = locals_.find(name);
if (it == locals_.end()) {
throw std::runtime_error("[irgen] 变量未找到: " + name);
auto* decl = sema_.ResolveVarUse(&primary);
if (!decl) {
throw std::runtime_error("[irgen] 变量使用缺少语义绑定: " +
primary.Ident()->getText());
}
auto it = storage_map_.find(decl);
if (it == storage_map_.end()) {
throw std::runtime_error("[irgen] 变量声明缺少存储槽位: " +
primary.Ident()->getText());
}
return builder_.CreateLoad(it->second, ir::DefaultContext().NextTemp());
}

View File

@@ -19,8 +19,8 @@ void VerifyFunctionStructure(const ir::Function& func) {
} // namespace
IRGenImpl::IRGenImpl(ir::Module& module)
: module_(module), func_(nullptr), builder_(nullptr) {}
IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
: module_(module), sema_(sema), func_(nullptr), builder_(nullptr) {}
void IRGenImpl::Gen(SysYParser::CompUnitContext& cu) {
if (!cu.funcDef()) {
@@ -39,7 +39,7 @@ void IRGenImpl::GenFuncDef(SysYParser::FuncDefContext& func) {
func_ = module_.CreateFunction(func.Ident()->getText(), ir::Type::Int32());
builder_.SetInsertPoint(func_->entry());
locals_.clear();
storage_map_.clear();
GenBlock(*func.block());
// 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。