From 4064885a1efff3c9d17eba2a3efa0b9082d01f2c Mon Sep 17 00:00:00 2001 From: hp <1278334840@qq.com> Date: Mon, 6 Apr 2026 21:25:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=B8=A6=E6=9C=89?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=9A=84=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ir/IR.h | 14 ++++++++++++ src/ir/Function.cpp | 11 +++++++++ src/ir/Value.cpp | 7 ++++++ src/irgen/IRGenFunc.cpp | 49 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 75 insertions(+), 6 deletions(-) diff --git a/include/ir/IR.h b/include/ir/IR.h index 24119af..4982988 100644 --- a/include/ir/IR.h +++ b/include/ir/IR.h @@ -144,6 +144,16 @@ class Value { std::vector uses_; }; +class Argument : public Value { + public: + Argument(std::shared_ptr ty, std::string name, Function* parent, size_t arg_no); + Function* GetParent() const; + size_t GetArgNo() const; + private: + Function* parent_; + size_t arg_no_; +}; + // ConstantValue 是常量体系的基类。 // 当前只实现了 ConstantInt,后续可继续扩展更多常量种类。 class ConstantValue : public Value { @@ -334,9 +344,13 @@ class Function : public Value { const BasicBlock* GetEntry() const; const std::vector>& GetBlocks() const; + Argument* AddArgument(std::shared_ptr ty, std::string name); + const std::vector>& GetArgs() const; + private: BasicBlock* entry_ = nullptr; std::vector> blocks_; + std::vector> args_; }; class Module { diff --git a/src/ir/Function.cpp b/src/ir/Function.cpp index cf14d48..5609718 100644 --- a/src/ir/Function.cpp +++ b/src/ir/Function.cpp @@ -29,4 +29,15 @@ const std::vector>& Function::GetBlocks() const { return blocks_; } +Argument* Function::AddArgument(std::shared_ptr ty, std::string name) { + auto arg = std::make_unique(std::move(ty), std::move(name), this, args_.size()); + auto* ptr = arg.get(); + args_.push_back(std::move(arg)); + return ptr; +} + +const std::vector>& Function::GetArgs() const { + return args_; +} + } // namespace ir diff --git a/src/ir/Value.cpp b/src/ir/Value.cpp index d8cbc8b..e3a81ec 100644 --- a/src/ir/Value.cpp +++ b/src/ir/Value.cpp @@ -112,6 +112,13 @@ void User::AddOperand(Value* value) { } } +Argument::Argument(std::shared_ptr ty, std::string name, Function* parent, size_t arg_no) + : Value(std::move(ty), std::move(name)), parent_(parent), arg_no_(arg_no) {} + +Function* Argument::GetParent() const { return parent_; } + +size_t Argument::GetArgNo() const { return arg_no_; } + ConstantValue::ConstantValue(std::shared_ptr ty, std::string name) : Value(std::move(ty), std::move(name)) {} diff --git a/src/irgen/IRGenFunc.cpp b/src/irgen/IRGenFunc.cpp index 0c8472e..bf4580f 100644 --- a/src/irgen/IRGenFunc.cpp +++ b/src/irgen/IRGenFunc.cpp @@ -69,22 +69,59 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) { if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少函数定义")); } - if (!ctx->block()) { + 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 函数")); + + std::shared_ptr ret_type; + if (ctx->funcType()->INT()) { + ret_type = ir::Type::GetInt32Type(); + } else if (ctx->funcType()->FLOAT()) { + ret_type = ir::Type::GetFloatType(); + } else if (ctx->funcType()->VOID()) { + ret_type = ir::Type::GetVoidType(); + } else { + throw std::runtime_error(FormatError("irgen", "未知的函数返回类型")); } - func_ = module_.CreateFunction(ctx->ID()->getText(), ir::Type::GetInt32Type()); + func_ = module_.CreateFunction(ctx->ID()->getText(), ret_type); builder_.SetInsertPoint(func_->GetEntry()); storage_map_.clear(); - ctx->block()->accept(this); - // 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。 + if (ctx->funcFParams()) { + for (auto* paramCtx : ctx->funcFParams()->funcFParam()) { + std::shared_ptr param_type; + bool is_array = !paramCtx->LBRACK().empty(); + + if (paramCtx->bType()->INT()) { + param_type = is_array ? ir::Type::GetPtrInt32Type() : ir::Type::GetInt32Type(); + } else if (paramCtx->bType()->FLOAT()) { + param_type = is_array ? ir::Type::GetPtrFloatType() : ir::Type::GetFloatType(); + } else { + throw std::runtime_error(FormatError("irgen", "未知的参数类型")); + } + + std::string arg_name = paramCtx->ID()->getText(); + auto* arg = func_->AddArgument(param_type, "%arg" + std::to_string(func_->GetArgs().size())); + + ir::Instruction* alloca_inst; + if (param_type->IsInt32() || param_type->IsPtrInt32()) { + alloca_inst = builder_.CreateAllocaI32(arg_name + ".addr"); + } else { + alloca_inst = builder_.CreateAllocaFloat(arg_name + ".addr"); + } + + builder_.CreateStore(arg, alloca_inst); + storage_map_[arg_name] = alloca_inst; + } + } + + ctx->blockStmt()->accept(this); + VerifyFunctionStructure(*func_); + func_ = nullptr; return {}; }