From 700bbb4e3b42069a975b1a9b8e49c7edc80fd2d8 Mon Sep 17 00:00:00 2001 From: LuoHello <2901023943@qq.com> Date: Tue, 31 Mar 2026 16:22:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A8=E5=B1=80=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=8F=8A=E5=B1=80=E9=83=A8=E5=8F=98=E9=87=8F=E5=8C=BA?= =?UTF-8?q?=E5=88=86=EF=BC=8C=E6=94=AF=E6=8C=81=E6=95=B4=E5=9E=8B=E5=B8=B8?= =?UTF-8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ir/IR.h | 131 ++++++++- include/irgen/IRGen.h | 42 ++- scripts/test_compiler.sh | 4 +- src/ir/Context.cpp | 60 +++- src/ir/GlobalValue.cpp | 118 +++++++- src/ir/IRBuilder.cpp | 15 + src/ir/IRPrinter.cpp | 24 ++ src/ir/Module.cpp | 16 +- src/ir/Value.cpp | 55 ++++ src/irgen/IRGenDecl.cpp | 599 ++++++++++++++++++++++++++++----------- src/irgen/IRGenExp.cpp | 108 +++++-- src/irgen/IRGenStmt.cpp | 119 ++++++-- src/sem/Sema.cpp | 4 +- 13 files changed, 1070 insertions(+), 225 deletions(-) diff --git a/include/ir/IR.h b/include/ir/IR.h index abe582d..d252ab3 100644 --- a/include/ir/IR.h +++ b/include/ir/IR.h @@ -47,6 +47,10 @@ class Value; class User; class ConstantValue; class ConstantInt; +class ConstantFloat; +class ConstantArray; +class ConstantZero; +class ConstantAggregateZero; class GlobalValue; class Instruction; class BasicBlock; @@ -79,17 +83,44 @@ class Use { }; // IR 上下文:集中管理类型、常量等共享资源,便于复用与扩展。 +// ir/IR.h - 修改 Context 类定义 + class Context { public: Context() = default; ~Context(); - // 去重创建 i32 常量。 + + // 去重创建 i32 常量 ConstantInt* GetConstInt(int v); + + // 去重创建浮点常量 + ConstantFloat* GetConstFloat(float v); + + // 创建数组常量(不去重,因为数组常量通常比较复杂且组合多样) + ConstantArray* GetConstArray(std::shared_ptr ty, + std::vector elements); + + // 获取零常量(按类型缓存) + ConstantZero* GetZeroConstant(std::shared_ptr ty); + + // 获取聚合类型的零常量 + ConstantAggregateZero* GetAggregateZero(std::shared_ptr ty); std::string NextTemp(); private: std::unordered_map> const_ints_; + + // 浮点常量:使用整数表示浮点数位模式作为键(避免浮点精度问题) + std::unordered_map> const_floats_; + + // 零常量缓存(按类型指针) + std::unordered_map> zero_constants_; + std::unordered_map> aggregate_zeros_; + + // 数组常量简单存储,不去重(因为数组常量通常组合多样,去重成本高) + std::vector> const_arrays_; + int temp_index_ = -1; }; @@ -220,6 +251,61 @@ class ConstantInt : public ConstantValue { private: int value_{}; }; + +// 在 ConstantInt 类之后添加以下类 + +// ConstantFloat - 浮点常量 +class ConstantFloat : public ConstantValue { + public: + ConstantFloat(std::shared_ptr ty, float v); + float GetValue() const { return value_; } + + private: + float value_{}; +}; + +// ConstantArray - 数组常量 +class ConstantArray : public ConstantValue { + public: + // 构造函数:接收数组类型和常量元素列表 + ConstantArray(std::shared_ptr ty, std::vector elements); + + // 获取元素数量 + size_t GetNumElements() const { return elements_.size(); } + + // 获取指定索引的元素 + ConstantValue* GetElement(size_t index) const { return elements_[index]; } + + // 获取所有元素 + const std::vector& GetElements() const { return elements_; } + + // 验证常量数组的类型是否正确 + bool IsValid() const; + + private: + std::vector elements_; +}; + +// ConstantZero - 零常量(用于零初始化) +class ConstantZero : public ConstantValue { + public: + explicit ConstantZero(std::shared_ptr ty); + + // 工厂方法:创建特定类型的零常量 + static std::unique_ptr GetZero(std::shared_ptr ty); +}; + +// ConstantAggregateZero - 聚合类型的零常量(数组、结构体等) +class ConstantAggregateZero : public ConstantValue { + public: + explicit ConstantAggregateZero(std::shared_ptr ty); + + // 获取聚合类型 + std::shared_ptr GetAggregateType() const { return GetType(); } + + // 工厂方法:创建聚合类型的零常量 + static std::unique_ptr GetZero(std::shared_ptr ty); +}; //function 参数占位类,目前仅保存类型和名字,后续可扩展更多属性(例如是否为数组参数、数组维度等)。 class Argument : public Value { public: @@ -265,9 +351,42 @@ class User : public Value { // GlobalValue 是全局值/全局变量体系的空壳占位类。 // 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。 +// ir/IR.h - 修正 GlobalValue 定义 +// ir/IR.h - 修正 GlobalValue 定义 class GlobalValue : public User { - public: +private: + std::vector initializer_; // 初始化值列表 + bool is_constant_ = false; // 是否为常量(如const变量) + bool is_extern_ = false; // 是否为外部声明 + +public: GlobalValue(std::shared_ptr ty, std::string name); + + // 初始化器相关 - 使用 ConstantValue* + void SetInitializer(ConstantValue* init); + void SetInitializer(const std::vector& init); + const std::vector& GetInitializer() const { return initializer_; } + bool HasInitializer() const { return !initializer_.empty(); } + + // 常量属性 + void SetConstant(bool is_const) { is_constant_ = is_const; } + bool IsConstant() const { return is_constant_; } + + // 外部声明 + void SetExtern(bool is_extern) { is_extern_ = is_extern; } + bool IsExtern() const { return is_extern_; } + + // 类型判断 - 使用 Type 的方法 + bool IsArray() const { return GetType()->IsArray(); } + bool IsScalar() const { return GetType()->IsInt32() || GetType()->IsFloat(); } + + // 获取数组大小(如果是数组类型) + int GetArraySize() const { + if (auto* array_ty = dynamic_cast(GetType().get())) { + return array_ty->GetElementCount(); + } + return 0; + } }; class Instruction : public User { @@ -617,6 +736,11 @@ class IRBuilder { // 构造常量、二元运算、返回指令的最小集合。 ConstantInt* CreateConstInt(int v); + ConstantFloat* CreateConstFloat(float v); // 新增 + ConstantArray* CreateConstArray(std::shared_ptr ty, + std::vector elements); // 新增 + ConstantZero* CreateZeroConstant(std::shared_ptr ty); // 新增 + BinaryInst* CreateBinary(Opcode op, Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name); @@ -675,6 +799,9 @@ class IRBuilder { class IRPrinter { public: void Print(const Module& module, std::ostream& os); + + private: + void PrintConstant(const ConstantValue* constant, std::ostream& os); }; } // namespace ir diff --git a/include/irgen/IRGen.h b/include/irgen/IRGen.h index c8c4c75..b61efcb 100644 --- a/include/irgen/IRGen.h +++ b/include/irgen/IRGen.h @@ -84,6 +84,12 @@ private: BlockFlow HandleContinueStmt(SysYParser::StmtContext* ctx); BlockFlow HandleAssignStmt(SysYParser::StmtContext* ctx); + // 完全正确的左值判断函数 + bool IsLValueExpression(SysYParser::ExpContext* ctx); + bool IsLValueInAddExp(SysYParser::AddExpContext* ctx); + bool IsLValueInMulExp(SysYParser::MulExpContext* ctx); + bool IsLValueInUnaryExp(SysYParser::UnaryExpContext* ctx); + bool IsLValueInPrimaryExp(SysYParser::PrimaryExpContext* ctx); // 循环上下文结构 struct LoopContext { ir::BasicBlock* condBlock; @@ -102,13 +108,41 @@ private: const SemanticContext& sema_; ir::Function* func_; ir::IRBuilder builder_; + ir::Value* EvalAssign(SysYParser::StmtContext* ctx); + + // 按 VarDefContext 查找存储位置(用于数组访问等场景) std::unordered_map storage_map_; - std::unordered_map const_storage_map_; // 新增 + + // 按变量名快速查找(用于 LVal 等场景) + std::unordered_map local_var_map_; // 局部变量 + std::unordered_map global_map_; // 全局变量 + std::unordered_map param_map_; // 函数参数 + + // 常量映射:常量名 -> 常量值(标量常量) + std::unordered_map const_value_map_; + + // 全局常量映射:常量名 -> 全局变量(数组常量) + std::unordered_map const_global_map_; + + // 原有的常量存储映射(用于兼容) + std::unordered_map const_storage_map_; + std::unordered_map array_info_map_; - ir::Value* EvalAssign(SysYParser::StmtContext* ctx); - std::unordered_map param_map_;// 函数参数映射,key 是参数名,value 是对应的 IR 值(通常是 AllocaInst 或 Function 参数) - std::unordered_map global_map_;// 全局变量映射,key 是全局变量名,value 是对应的 IR 值(通常是 GlobalValue) + + // 新增:处理全局和局部变量的辅助函数 + std::any HandleGlobalVariable(SysYParser::VarDefContext* ctx, + const std::string& varName, + bool is_array); + std::any HandleLocalVariable(SysYParser::VarDefContext* ctx, + const std::string& varName, + bool is_array); + // 常量求值辅助函数 + int EvaluateConstAddExp(SysYParser::AddExpContext* ctx); + int EvaluateConstMulExp(SysYParser::MulExpContext* ctx); + int EvaluateConstUnaryExp(SysYParser::UnaryExpContext* ctx); + int EvaluateConstPrimaryExp(SysYParser::PrimaryExpContext* ctx); + int EvaluateConstExp(SysYParser::ExpContext* ctx); }; std::unique_ptr GenerateIR(SysYParser::CompUnitContext& tree, diff --git a/scripts/test_compiler.sh b/scripts/test_compiler.sh index 082846c..5045b56 100755 --- a/scripts/test_compiler.sh +++ b/scripts/test_compiler.sh @@ -67,7 +67,7 @@ for test_dir in "${TEST_DIRS[@]}"; do # 检查是否生成了有效的函数定义(在过滤后的内容中检查) # 先过滤一下看看是否有define - filtered_content=$(sed -E '/^\[DEBUG\]|^SymbolTable::|^CheckLValue:|^绑定变量:|^dim_count:/d' "$raw_ll") + filtered_content=$(sed -E '/^\[DEBUG\]|^SymbolTable::|^Check|^绑定|^保存|^dim_count:/d' "$raw_ll") if ! echo "$filtered_content" | grep -qE '^define '; then echo " [IR] 失败: 未生成有效函数定义" ir_failures+=("$input: invalid IR output") @@ -85,7 +85,7 @@ for test_dir in "${TEST_DIRS[@]}"; do # 4. 绑定变量: 开头的行 # 5. dim_count: 开头的行 # 6. 空行(可选) - sed -E '/^(\[DEBUG|SymbolTable::|CheckLValue|绑定变量:|dim_)/d' "$raw_ll" > "$ll_file" + sed -E '/^(\[DEBUG|SymbolTable::|Check|绑定|保存|dim_)/d' "$raw_ll" > "$ll_file" # 可选:删除多余的空行 sed -i '/^$/N;/\n$/D' "$ll_file" diff --git a/src/ir/Context.cpp b/src/ir/Context.cpp index 5f32c65..2059cde 100644 --- a/src/ir/Context.cpp +++ b/src/ir/Context.cpp @@ -1,6 +1,8 @@ // 管理基础类型、整型常量池和临时名生成。 -#include "ir/IR.h" +// ir/IR.cpp +#include "ir/IR.h" +#include // for memcpy #include namespace ir { @@ -15,10 +17,64 @@ ConstantInt* Context::GetConstInt(int v) { return inserted->second.get(); } +// 新增:获取浮点常量 +ConstantFloat* Context::GetConstFloat(float v) { + // 使用浮点数的二进制表示作为键,避免精度问题 + uint32_t key; + std::memcpy(&key, &v, sizeof(float)); + + auto it = const_floats_.find(key); + if (it != const_floats_.end()) { + return it->second.get(); + } + + auto float_ty = Type::GetFloatType(); + auto constant = std::make_unique(float_ty, v); + auto* ptr = constant.get(); + const_floats_[key] = std::move(constant); + return ptr; +} + +// 新增:创建数组常量 +ConstantArray* Context::GetConstArray(std::shared_ptr ty, + std::vector elements) { + auto constant = std::make_unique(ty, std::move(elements)); + auto* ptr = constant.get(); + const_arrays_.push_back(std::move(constant)); + return ptr; +} + +// 新增:获取零常量 +ConstantZero* Context::GetZeroConstant(std::shared_ptr ty) { + auto it = zero_constants_.find(ty.get()); + if (it != zero_constants_.end()) { + return it->second.get(); + } + + auto constant = std::make_unique(ty); + auto* ptr = constant.get(); + zero_constants_[ty.get()] = std::move(constant); + return ptr; +} + +// 新增:获取聚合类型的零常量 +ConstantAggregateZero* Context::GetAggregateZero(std::shared_ptr ty) { + auto it = aggregate_zeros_.find(ty.get()); + if (it != aggregate_zeros_.end()) { + return it->second.get(); + } + + auto constant = std::make_unique(ty); + auto* ptr = constant.get(); + aggregate_zeros_[ty.get()] = std::move(constant); + return ptr; +} + std::string Context::NextTemp() { std::ostringstream oss; oss << "%t" << ++temp_index_; return oss.str(); } -} // namespace ir + +} // namespace ir \ No newline at end of file diff --git a/src/ir/GlobalValue.cpp b/src/ir/GlobalValue.cpp index 7c2abe1..5b68e0b 100644 --- a/src/ir/GlobalValue.cpp +++ b/src/ir/GlobalValue.cpp @@ -1,11 +1,121 @@ -// GlobalValue 占位实现: -// - 具体的全局初始化器、打印和链接语义需要自行补全 - +// ir/GlobalValue.cpp #include "ir/IR.h" +#include namespace ir { GlobalValue::GlobalValue(std::shared_ptr ty, std::string name) : User(std::move(ty), std::move(name)) {} -} // namespace ir +void GlobalValue::SetInitializer(ConstantValue* init) { + if (!init) { + throw std::runtime_error("GlobalValue::SetInitializer: init is null"); + } + + // 获取实际的值类型(用于类型检查) + std::shared_ptr value_type; + + // 如果当前类型是指针,获取指向的值类型 + if (GetType()->IsPtrInt32()) { + value_type = Type::GetInt32Type(); + } else if (GetType()->IsPtrFloat()) { + value_type = Type::GetFloatType(); + } else if (GetType()->IsPtrInt1()) { + value_type = Type::GetInt1Type(); + } else { + // 非指针类型:直接使用当前类型 + value_type = GetType(); + } + + // 类型检查 + bool type_match = false; + + // 检查标量类型 + if (value_type->IsInt32() && init->GetType()->IsInt32()) { + type_match = true; + } else if (value_type->IsFloat() && init->GetType()->IsFloat()) { + type_match = true; + } else if (value_type->IsInt1() && init->GetType()->IsInt1()) { + type_match = true; + } + // 检查数组类型:允许用单个标量初始化整个数组 + else if (value_type->IsArray()) { + auto* array_ty = static_cast(value_type.get()); + auto* elem_type = array_ty->GetElementType().get(); + + if (elem_type->IsInt32() && init->GetType()->IsInt32()) { + type_match = true; + } else if (elem_type->IsFloat() && init->GetType()->IsFloat()) { + type_match = true; + } + } + + if (!type_match) { + throw std::runtime_error("GlobalValue::SetInitializer: type mismatch"); + } + + initializer_.clear(); + initializer_.push_back(init); +} + +void GlobalValue::SetInitializer(const std::vector& init) { + if (init.empty()) { + return; + } + + // 获取实际的值类型 + std::shared_ptr value_type; + + if (GetType()->IsPtrInt32()) { + value_type = Type::GetInt32Type(); + } else if (GetType()->IsPtrFloat()) { + value_type = Type::GetFloatType(); + } else if (GetType()->IsPtrInt1()) { + value_type = Type::GetInt1Type(); + } else { + value_type = GetType(); + } + + // 检查类型 + if (value_type->IsArray()) { + auto* array_ty = static_cast(value_type.get()); + size_t array_size = array_ty->GetElementCount(); + + if (init.size() > array_size) { + throw std::runtime_error("GlobalValue::SetInitializer: too many initializers"); + } + + // 检查每个初始化值的类型 + auto* elem_type = array_ty->GetElementType().get(); + for (auto* elem : init) { + bool elem_match = false; + if (elem_type->IsInt32() && elem->GetType()->IsInt32()) { + elem_match = true; + } else if (elem_type->IsFloat() && elem->GetType()->IsFloat()) { + elem_match = true; + } + + if (!elem_match) { + throw std::runtime_error("GlobalValue::SetInitializer: element type mismatch"); + } + } + } + else if (value_type->IsInt32() || value_type->IsFloat() || value_type->IsInt1()) { + if (init.size() != 1) { + throw std::runtime_error("GlobalValue::SetInitializer: scalar requires exactly one initializer"); + } + + if ((value_type->IsInt32() && !init[0]->GetType()->IsInt32()) || + (value_type->IsFloat() && !init[0]->GetType()->IsFloat()) || + (value_type->IsInt1() && !init[0]->GetType()->IsInt1())) { + throw std::runtime_error("GlobalValue::SetInitializer: type mismatch"); + } + } + else { + throw std::runtime_error("GlobalValue::SetInitializer: unsupported type"); + } + + initializer_ = init; +} + +} // namespace ir \ No newline at end of file diff --git a/src/ir/IRBuilder.cpp b/src/ir/IRBuilder.cpp index 0665d59..a91f081 100644 --- a/src/ir/IRBuilder.cpp +++ b/src/ir/IRBuilder.cpp @@ -21,6 +21,21 @@ ConstantInt* IRBuilder::CreateConstInt(int v) { return ctx_.GetConstInt(v); } +// IRBuilder 方法实现 +ConstantFloat* IRBuilder::CreateConstFloat(float v) { + return ctx_.GetConstFloat(v); +} + +ConstantArray* IRBuilder::CreateConstArray(std::shared_ptr ty, + std::vector elements) { + return ctx_.GetConstArray(ty, std::move(elements)); +} + +ConstantZero* IRBuilder::CreateZeroConstant(std::shared_ptr ty) { + return ctx_.GetZeroConstant(ty); +} + + BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs, const std::string& name) { if (!insert_block_) { diff --git a/src/ir/IRPrinter.cpp b/src/ir/IRPrinter.cpp index beb6ca8..053274a 100644 --- a/src/ir/IRPrinter.cpp +++ b/src/ir/IRPrinter.cpp @@ -261,4 +261,28 @@ void IRPrinter::Print(const Module& module, std::ostream& os) { } } +void IRPrinter::PrintConstant(const ConstantValue* constant, std::ostream& os) { + if (auto* const_int = dynamic_cast(constant)) { + os << const_int->GetValue(); + } + else if (auto* const_float = dynamic_cast(constant)) { + os << const_float->GetValue(); + } + else if (auto* const_array = dynamic_cast(constant)) { + os << "["; + auto& elements = const_array->GetElements(); + for (size_t i = 0; i < elements.size(); ++i) { + if (i > 0) os << ", "; + PrintConstant(elements[i], os); + } + os << "]"; + } + else if (auto* zero = dynamic_cast(constant)) { + os << "zero"; + } + else if (auto* agg_zero = dynamic_cast(constant)) { + os << "zeroinitializer"; + } +} + } // namespace ir diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 76eb1eb..79e41a5 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -29,7 +29,21 @@ const std::vector>& Module::GetFunctions() const { GlobalValue* Module::CreateGlobal(const std::string& name, std::shared_ptr ty) { - globals_.push_back(std::make_unique(ty, name)); + // 对于标量类型,自动转换为指针类型 + std::shared_ptr global_ty; + + if (ty->IsInt32()) { + global_ty = Type::GetPtrInt32Type(); // i32 -> i32* + } else if (ty->IsFloat()) { + global_ty = Type::GetPtrFloatType(); // float -> float* + } else if (ty->IsInt1()) { + global_ty = Type::GetPtrInt1Type(); // i1 -> i1* + } else { + // 数组等类型保持不变 + global_ty = ty; + } + + globals_.push_back(std::make_unique(global_ty, name)); return globals_.back().get(); } diff --git a/src/ir/Value.cpp b/src/ir/Value.cpp index 68b6ab4..56dd2e6 100644 --- a/src/ir/Value.cpp +++ b/src/ir/Value.cpp @@ -82,4 +82,59 @@ Argument::Argument(std::shared_ptr ty, std::string name) ConstantInt::ConstantInt(std::shared_ptr ty, int v) : ConstantValue(std::move(ty), ""), value_(v) {} + +// ConstantFloat 实现 +ConstantFloat::ConstantFloat(std::shared_ptr ty, float v) + : ConstantValue(ty, ""), value_(v) { + if (!ty->IsFloat()) { + throw std::runtime_error("ConstantFloat requires Float type"); + } +} + +// ConstantArray 实现 +ConstantArray::ConstantArray(std::shared_ptr ty, + std::vector elements) + : ConstantValue(ty, ""), elements_(std::move(elements)) { + if (!IsValid()) { + throw std::runtime_error("Invalid constant array initialization"); + } +} + +bool ConstantArray::IsValid() const { + auto* array_ty = dynamic_cast(GetType().get()); + if (!array_ty) return false; + + // 检查元素数量是否匹配 + if (elements_.size() != array_ty->GetElementCount()) return false; + + // 检查每个元素的类型是否匹配数组元素类型 + auto& elem_ty = array_ty->GetElementType(); + for (auto* elem : elements_) { + if (elem->GetType() != elem_ty) return false; + } + + return true; +} + +// ConstantZero 实现 +ConstantZero::ConstantZero(std::shared_ptr ty) + : ConstantValue(ty, "zero") { + // 零常量可以用于任何类型 +} + +std::unique_ptr ConstantZero::GetZero(std::shared_ptr ty) { + return std::make_unique(ty); +} + +// ConstantAggregateZero 实现 +ConstantAggregateZero::ConstantAggregateZero(std::shared_ptr ty) + : ConstantValue(ty, "zero") { + if (!ty->IsArray()) { + throw std::runtime_error("ConstantAggregateZero requires aggregate type"); + } +} + +std::unique_ptr ConstantAggregateZero::GetZero(std::shared_ptr ty) { + return std::make_unique(ty); +} } // namespace ir diff --git a/src/irgen/IRGenDecl.cpp b/src/irgen/IRGenDecl.cpp index 4ec2a95..bc8e2d8 100644 --- a/src/irgen/IRGenDecl.cpp +++ b/src/irgen/IRGenDecl.cpp @@ -30,12 +30,14 @@ int TryGetConstInt(SysYParser::ConstExpContext* ctx) { // 注意:visitBlock 已经在 IRGenFunc.cpp 中实现,这里不要重复定义 std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) { + std::cerr << "[DEBUG] visitDecl: 开始处理声明" << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少变量声明")); } // 处理 varDecl if (auto* varDecl = ctx->varDecl()) { + std::cerr << "[DEBUG] visitDecl: 处理变量声明" << std::endl; // 检查类型 if (varDecl->bType() && varDecl->bType()->Int()) { for (auto* varDef : varDecl->varDef()) { @@ -48,6 +50,7 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) { // 处理 constDecl if (ctx->constDecl()) { + std::cerr << "[DEBUG] visitDecl: 处理常量声明" << std::endl; auto* constDecl = ctx->constDecl(); if (constDecl->bType() && constDecl->bType()->Int()) { @@ -60,11 +63,13 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) { throw std::runtime_error(FormatError("irgen", "未知的常量类型")); } } + std::cerr << "[DEBUG] visitDecl: 声明处理完成" << std::endl; return {}; } // 在 IRGenDecl.cpp 中确保有这个函数 std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) { + std::cerr << "[DEBUG] visitConstDecl: 开始处理常量声明" << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法常量声明")); } @@ -90,10 +95,10 @@ std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) { throw std::runtime_error(FormatError("irgen", "常量声明缺少类型")); } + std::cerr << "[DEBUG] visitConstDecl: 常量声明处理完成" << std::endl; return {}; } -// 修改 visitConstDef 函数,正确处理数组大小 std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) { if (!ctx || !ctx->Ident()) { throw std::runtime_error(FormatError("irgen", "非法常量定义")); @@ -106,147 +111,103 @@ std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) { bool is_array = !ctx->constExp().empty(); if (is_array) { - // 数组常量处理 + // 数组常量处理 - 创建全局常量数组 std::cerr << "[DEBUG] visitConstDef: array constant " << const_name << std::endl; // 获取数组维度 - int array_size = 0; - - if (!ctx->constExp().empty()) { - // 尝试获取数组大小 - try { - // 使用辅助函数获取整数值 - array_size = TryEvaluateConstInt(ctx->constExp()[0]); - if (array_size <= 0) { - // 如果获取失败,使用默认值10 - array_size = 10; - } - } catch (const std::exception& e) { - // 注意:这里错误信息应该是 visitConstDef,不是 visitVarDef - std::cerr << "[WARNING] visitConstDef: 无法获取数组大小: " << e.what() - << ",使用默认值10" << std::endl; - array_size = 10; - } - } - - if (array_size <= 0) { - throw std::runtime_error(FormatError("irgen", "常量数组大小必须为正数")); - } - - if (array_size > 1000) { - throw std::runtime_error(FormatError("irgen", "常量数组大小太大")); + std::vector dimensions; + for (auto* const_exp : ctx->constExp()) { + int dim_size = TryEvaluateConstInt(const_exp); + if (dim_size <= 0) dim_size = 1; + dimensions.push_back(dim_size); } - // 分配数组存储 - std::vector element_slots; - for (int i = 0; i < array_size; i++) { - auto* slot = builder_.CreateAllocaI32( - module_.GetContext().NextTemp() + "_" + const_name + "_" + std::to_string(i)); - element_slots.push_back(slot); - } + // 创建数组类型 + auto array_type = ir::Type::GetArrayType(ir::Type::GetInt32Type(), dimensions); + ir::GlobalValue* global_array = module_.CreateGlobal(const_name, array_type); - // 处理初始化 + // 处理初始化值 + std::vector init_consts; if (auto* const_init_val = ctx->constInitVal()) { - // 获取初始化值 auto result = const_init_val->accept(this); - if (result.has_value()) { try { - std::vector init_values = - std::any_cast>(result); - - // 检查初始化值数量 - if (init_values.size() > static_cast(array_size)) { - throw std::runtime_error( - FormatError("irgen", "常量数组初始化值太多,数组大小为" + std::to_string(array_size) + - ",但提供了" + std::to_string(init_values.size()) + "个值")); - } - - // 使用初始化值初始化数组元素 - for (size_t i = 0; i < init_values.size(); i++) { - builder_.CreateStore(init_values[i], element_slots[i]); - } - - // 剩余元素初始化为0 - for (size_t i = init_values.size(); i < static_cast(array_size); i++) { - builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); + auto init_vec = std::any_cast>(result); + for (auto* val : init_vec) { + if (auto* const_int = dynamic_cast(val)) { + init_consts.push_back(const_int); + } else { + init_consts.push_back(builder_.CreateConstInt(0)); + } } } catch (const std::bad_any_cast&) { - // 可能返回的是单个值 try { - ir::Value* single_value = std::any_cast(result); - // 只初始化第一个元素 - builder_.CreateStore(single_value, element_slots[0]); - - // 其他元素初始化为0 - for (int i = 1; i < array_size; i++) { - builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); - } - } catch (const std::bad_any_cast&) { - std::cerr << "[ERROR] visitConstDef: 无法解析常量数组初始化值类型" << std::endl; - // 全部初始化为0 - for (int i = 0; i < array_size; i++) { - builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); + ir::Value* single_val = std::any_cast(result); + if (auto* const_int = dynamic_cast(single_val)) { + init_consts.push_back(const_int); } - } - } - } else { - // 没有初始化值,全部初始化为0 - for (int i = 0; i < array_size; i++) { - builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); + } catch (...) {} } } - } else { - // 常量数组缺少初始值 - throw std::runtime_error(FormatError("irgen", "常量数组缺少初始值")); } - // 存储第一个元素的地址到 const_storage_map_ - const_storage_map_[ctx] = element_slots[0]; + // 补0 + int total_size = 1; + for (int dim : dimensions) total_size *= dim; + while (init_consts.size() < static_cast(total_size)) { + init_consts.push_back(builder_.CreateConstInt(0)); + } + + global_array->SetInitializer(init_consts); + global_array->SetConstant(true); + + // 存储到常量映射(而不是storage_map_) + const_storage_map_[ctx] = global_array; + const_global_map_[const_name] = global_array; - std::cerr << "[DEBUG] visitConstDef: 创建常量数组 " << const_name - << ",大小 " << array_size << std::endl; } else { - // 标量常量处理 + // 标量常量处理 - 直接求值并存储常量值 std::cerr << "[DEBUG] visitConstDef: scalar constant " << const_name << std::endl; if (!ctx->constInitVal()) { throw std::runtime_error(FormatError("irgen", "常量缺少初始值")); } - // 处理常量初始化值 + // 求值常量表达式 + // 求值常量表达式 auto* const_init_val = ctx->constInitVal(); - auto result = const_init_val->accept(this); - if (result.has_value()) { - try { - ir::Value* const_value = std::any_cast(result); - std::cerr << "[DEBUG] visitConstDef: scalar constant " << const_name - << " with value " << (void*)const_value << std::endl; - - // 标量常量也需要存储槽位,以便后续引用 - auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name); - const_storage_map_[ctx] = slot; - builder_.CreateStore(const_value, slot); - - return {}; - } catch (const std::bad_any_cast& e) { - std::cerr << "[ERROR] visitConstDef: bad any_cast for scalar constant " << const_name << ": " << e.what() << std::endl; - throw std::runtime_error(FormatError("irgen", "标量常量初始化值类型错误")); - } + // 关键修改:直接求值常量表达式,不使用 builder_ + ir::ConstantValue* const_value = nullptr; + + if (const_init_val->constExp()) { + // 直接访问常量表达式的值,不通过 IR 生成 + int value = TryEvaluateConstInt(const_init_val->constExp()); + // 使用 Context 直接创建常量,不依赖 builder_ + const_value = module_.GetContext().GetConstInt(value); + std::cerr << "[DEBUG] visitConstDef: constant " << const_name + << " = " << value << std::endl; + } else { + const_value = module_.GetContext().GetConstInt(0); } - // 如果求值失败,使用默认值0 - ir::Value* default_value = builder_.CreateConstInt(0); - auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name); - const_storage_map_[ctx] = slot; - builder_.CreateStore(default_value, slot); + // 存储常量值到映射 + const_value_map_[const_name] = const_value; + + // 同时也保存一个虚拟指针用于统一接口(可选) + // auto* dummy_slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name); + // builder_.CreateStore(const_value, dummy_slot); + // const_storage_map_[ctx] = dummy_slot; + std::cerr << "[DEBUG] visitConstDef: scalar constant stored, no alloca created" << std::endl; } return {}; } + + // TO DO:visitVarDef来区分全局和局部变量,并且正确处理数组变量的定义和初始化 std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) { + std::cerr << "[DEBUG] visitVarDef: 开始处理变量定义" << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少变量定义")); } @@ -256,91 +217,258 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) { } std::string varName = ctx->Ident()->getText(); + std::cerr << "[DEBUG] visitVarDef: 变量名称: " << varName << std::endl; // 防止同一个变量被多次分配存储空间。 if (storage_map_.find(ctx) != storage_map_.end()) { throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName)); } bool is_array = !ctx->constExp().empty(); + std::cerr << "[DEBUG] visitVarDef: 是否为数组: " << (is_array ? "是" : "否") << std::endl; + // 使用 func_ 来判断:func_ == nullptr 表示在全局作用域 + if (func_ == nullptr) { + std::cerr << "[DEBUG] visitVarDef: 处理全局变量" << std::endl; + // 全局变量处理 + return HandleGlobalVariable(ctx, varName, is_array); + } else { + std::cerr << "[DEBUG] visitVarDef: 处理局部变量" << std::endl; + // 局部变量处理 + return HandleLocalVariable(ctx, varName, is_array); + } +} + +std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx, + const std::string& varName, + bool is_array) { + std::cerr << "[DEBUG] HandleGlobalVariable: 开始处理全局变量 " << varName << std::endl; if (is_array) { - // 数组变量 - // 获取数组维度 + std::cerr << "[DEBUG] HandleGlobalVariable: 处理全局数组变量" << std::endl; + // 全局数组变量 int total_size = 1; std::vector dimensions; + + // 计算总大小 + for (auto* const_exp : ctx->constExp()) { + int dim_size = TryEvaluateConstInt(const_exp); + if (dim_size <= 0) { + dim_size = 1; + std::cerr << "[WARNING] HandleGlobalVariable: 无法确定数组维度大小,使用1" << std::endl; + } + dimensions.push_back(dim_size); + total_size *= dim_size; + } + + std::cerr << "[DEBUG] HandleGlobalVariable: 数组总大小: " << total_size << std::endl; + + if (total_size <= 0 || total_size > 10000) { + throw std::runtime_error(FormatError("irgen", "全局数组大小无效")); + } + + // 创建数组类型的全局变量 + auto array_type = ir::Type::GetArrayType(ir::Type::GetInt32Type(), dimensions); + ir::GlobalValue* global_array = module_.CreateGlobal(varName, array_type); + std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局数组: " << varName << std::endl; + + // 处理初始化值 + std::vector init_consts; + if (auto* initVal = ctx->initVal()) { + std::cerr << "[DEBUG] HandleGlobalVariable: 处理初始化值" << std::endl; + auto result = initVal->accept(this); + if (result.has_value()) { + try { + // 尝试获取初始化值列表 + auto init_vec = std::any_cast>(result); + std::cerr << "[DEBUG] HandleGlobalVariable: 获取到初始化值列表, 大小: " << init_vec.size() << std::endl; + for (auto* val : init_vec) { + if (auto* const_int = dynamic_cast(val)) { + init_consts.push_back(const_int); + } else { + // 非常量表达式,使用0 + init_consts.push_back(builder_.CreateConstInt(0)); + } + } + } catch (const std::bad_any_cast&) { + try { + // 可能是单个值 + ir::Value* single_val = std::any_cast(result); + std::cerr << "[DEBUG] HandleGlobalVariable: 获取到单个初始化值" << std::endl; + if (auto* const_int = dynamic_cast(single_val)) { + init_consts.push_back(const_int); + } else { + init_consts.push_back(builder_.CreateConstInt(0)); + } + } catch (const std::bad_any_cast&) { + std::cerr << "[WARNING] HandleGlobalVariable: 无法解析数组初始化值" << std::endl; + } + } + } + } + + // 如果初始化值不足,补0 + while (init_consts.size() < static_cast(total_size)) { + init_consts.push_back(builder_.CreateConstInt(0)); + } + + // 设置全局数组的初始化器 + if (!init_consts.empty()) { + global_array->SetInitializer(init_consts); + std::cerr << "[DEBUG] HandleGlobalVariable: 设置全局数组初始化器" << std::endl; + } + + // 判断是否为常量(检查父节点是否为 ConstDef) + if (ctx->parent && dynamic_cast(ctx->parent)) { + global_array->SetConstant(true); + std::cerr << "[DEBUG] HandleGlobalVariable: 设置为常量数组" << std::endl; + } + + // 存储全局变量引用 + storage_map_[ctx] = global_array; + global_map_[varName] = global_array;//按名称映射 + std::cerr << "[DEBUG] HandleGlobalVariable: 存储全局数组引用" << std::endl; + + // 保存数组信息 + ArrayInfo info; + info.elements.clear(); // 全局数组不预先分配元素槽位 + info.dimensions = dimensions; + array_info_map_[ctx] = info; + + std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局数组 " << varName + << ",总大小 " << total_size << std::endl; + } else { + std::cerr << "[DEBUG] HandleGlobalVariable: 处理全局标量变量" << std::endl; + // 全局标量变量 + ir::GlobalValue* global_var = module_.CreateGlobal(varName, ir::Type::GetInt32Type()); + std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局标量变量: " << varName << std::endl; + + // 处理初始化值 + ir::ConstantValue* init_value = nullptr; + if (auto* initVal = ctx->initVal()) { + std::cerr << "[DEBUG] HandleGlobalVariable: 处理标量初始化值" << std::endl; + auto result = initVal->accept(this); + if (result.has_value()) { + try { + ir::Value* val = std::any_cast(result); + if (auto* const_int = dynamic_cast(val)) { + init_value = const_int; + std::cerr << "[DEBUG] HandleGlobalVariable: 获取到常量初始化值" << std::endl; + } else { + // 默认初始化为0 + init_value = builder_.CreateConstInt(0); + std::cerr << "[DEBUG] HandleGlobalVariable: 使用默认初始化值0" << std::endl; + } + } catch (const std::bad_any_cast&) { + init_value = builder_.CreateConstInt(0); + std::cerr << "[DEBUG] HandleGlobalVariable: 类型转换失败,使用默认初始化值0" << std::endl; + } + } else { + std::cerr << "[DEBUG] HandleGlobalVariable: 无初始化值结果" << std::endl; + } + } else { + std::cerr << "[DEBUG] HandleGlobalVariable: 无初始化值" << std::endl; + } + + // 如果没有初始化值,默认初始化为0 + if (!init_value) { + init_value = builder_.CreateConstInt(0); + std::cerr << "[DEBUG] HandleGlobalVariable: 使用默认初始化值0" << std::endl; + } + + // 设置全局变量的初始化器 + global_var->SetInitializer(init_value); + std::cerr << "[DEBUG] HandleGlobalVariable: 设置全局变量初始化器" << std::endl; + + // 判断是否为常量 + if (ctx->parent && dynamic_cast(ctx->parent)) { + global_var->SetConstant(true); + std::cerr << "[DEBUG] HandleGlobalVariable: 设置为常量" << std::endl; + } + + // 存储全局变量引用 + storage_map_[ctx] = global_var; + global_map_[varName] = global_var; + std::cerr << "[DEBUG] HandleGlobalVariable: 存储全局变量引用" << std::endl; + + std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局变量 " << varName << std::endl; + } + + std::cerr << "[DEBUG] HandleGlobalVariable: 全局变量处理完成" << std::endl; + return {}; +} - // 计算所有维度 +std::any IRGenImpl::HandleLocalVariable(SysYParser::VarDefContext* ctx, + const std::string& varName, + bool is_array) { + std::cerr << "[DEBUG] HandleLocalVariable: 开始处理局部变量 " << varName << std::endl; + if (is_array) { + std::cerr << "[DEBUG] HandleLocalVariable: 处理局部数组变量" << std::endl; + // 局部数组变量 + int total_size = 1; + std::vector dimensions; + + // 获取数组维度 for (auto* const_exp : ctx->constExp()) { try { int dim_size = TryEvaluateConstInt(const_exp); if (dim_size <= 0) { - // 如果维度大小未知,使用默认值 dim_size = 1; - std::cerr << "[WARNING] visitVarDef: 无法确定数组维度大小,使用1" << std::endl; + std::cerr << "[WARNING] HandleLocalVariable: 无法确定数组维度大小,使用1" << std::endl; } dimensions.push_back(dim_size); total_size *= dim_size; } catch (const std::exception& e) { - std::cerr << "[WARNING] visitVarDef: 无法获取数组维度: " << e.what() + std::cerr << "[WARNING] HandleLocalVariable: 无法获取数组维度: " << e.what() << ",使用维度1" << std::endl; dimensions.push_back(1); total_size *= 1; } } - + + std::cerr << "[DEBUG] HandleLocalVariable: 数组总大小: " << total_size << std::endl; + if (total_size <= 0) { throw std::runtime_error(FormatError("irgen", "数组大小必须为正数")); } - - if (total_size > 1000) { + + if (total_size > 10000) { throw std::runtime_error(FormatError("irgen", "数组大小太大")); } - - // 分配数组存储 + + // 分配数组存储 - 为每个元素创建独立的 alloca std::vector element_slots; + std::cerr << "[DEBUG] HandleLocalVariable: 为数组元素分配存储空间" << std::endl; for (int i = 0; i < total_size; i++) { auto* slot = builder_.CreateAllocaI32( module_.GetContext().NextTemp() + "_" + varName + "_" + std::to_string(i)); element_slots.push_back(slot); } - + // 处理初始化 if (auto* initVal = ctx->initVal()) { - // 获取初始化值 + std::cerr << "[DEBUG] HandleLocalVariable: 处理数组初始化值" << std::endl; auto result = initVal->accept(this); if (result.has_value()) { try { + // 尝试获取初始化值列表 std::vector init_values = std::any_cast>(result); + std::cerr << "[DEBUG] HandleLocalVariable: 获取到初始化值列表, 大小: " << init_values.size() << std::endl; - // 检查初始化值数量 - if (init_values.size() > static_cast(total_size)) { - // 对于多维数组,这可能是正常的 - // 我们打印警告但继续执行 - std::cerr << "[WARNING] visitVarDef: 初始化值(" << init_values.size() - << ")超过数组总大小(" << total_size - << "),只初始化前" << total_size << "个元素" << std::endl; - - // 只初始化能容纳的部分 - for (size_t i = 0; i < static_cast(total_size); i++) { - builder_.CreateStore(init_values[i], element_slots[i]); - } - } else { - // 正常初始化 - for (size_t i = 0; i < init_values.size(); i++) { - builder_.CreateStore(init_values[i], element_slots[i]); - } - - // 剩余元素初始化为0 - for (size_t i = init_values.size(); i < static_cast(total_size); i++) { - builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); - } + // 初始化数组元素 + for (size_t i = 0; i < init_values.size() && i < static_cast(total_size); i++) { + builder_.CreateStore(init_values[i], element_slots[i]); + } + + // 剩余元素初始化为0 + for (size_t i = init_values.size(); i < static_cast(total_size); i++) { + builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); } } catch (const std::bad_any_cast&) { // 可能返回的是单个值 try { ir::Value* single_value = std::any_cast(result); + std::cerr << "[DEBUG] HandleLocalVariable: 获取到单个初始化值" << std::endl; // 只初始化第一个元素 builder_.CreateStore(single_value, element_slots[0]); @@ -349,7 +477,7 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) { builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); } } catch (const std::bad_any_cast&) { - std::cerr << "[ERROR] visitVarDef: 无法解析数组初始化值类型" << std::endl; + std::cerr << "[ERROR] HandleLocalVariable: 无法解析数组初始化值类型" << std::endl; // 全部初始化为0 for (int i = 0; i < total_size; i++) { builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); @@ -357,45 +485,56 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) { } } } else { + std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值结果" << std::endl; // 没有初始化值,全部初始化为0 for (int i = 0; i < total_size; i++) { builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); } } } else { + std::cerr << "[DEBUG] HandleLocalVariable: 无初始化,全部初始化为0" << std::endl; // 无初始化,所有元素初始化为0 for (int i = 0; i < total_size; i++) { builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); } } - - // 存储第一个元素的地址 + + // 存储第一个元素的地址作为数组的基地址 storage_map_[ctx] = element_slots[0]; - + local_var_map_[varName] = element_slots[0]; // 添加到局部变量映射,按名称映射 + std::cerr << "[DEBUG] HandleLocalVariable: 存储数组引用" << std::endl; + // 保存数组信息 ArrayInfo info; info.elements = element_slots; info.dimensions = dimensions; array_info_map_[ctx] = info; - - std::cerr << "[DEBUG] visitVarDef: 创建数组 " << varName + + std::cerr << "[DEBUG] HandleLocalVariable: 创建局部数组 " << varName << ",维度 "; for (size_t i = 0; i < dimensions.size(); i++) { std::cerr << dimensions[i]; if (i < dimensions.size() - 1) std::cerr << "×"; } std::cerr << ",总大小 " << total_size << std::endl; - } else { - // 标量变量 + + } else { + std::cerr << "[DEBUG] HandleLocalVariable: 处理局部标量变量" << std::endl; + // 局部标量变量 auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + varName); storage_map_[ctx] = slot; + local_var_map_[varName] = slot; // 添加到局部变量映射 + std::cerr << "[DEBUG] HandleLocalVariable: 创建局部标量变量存储槽" << std::endl; + // 处理初始化 ir::Value* init = nullptr; if (auto* initVal = ctx->initVal()) { + std::cerr << "[DEBUG] HandleLocalVariable: 处理标量初始化值" << std::endl; auto result = initVal->accept(this); if (result.has_value()) { try { init = std::any_cast(result); + std::cerr << "[DEBUG] HandleLocalVariable: 获取到初始化值" << std::endl; } catch (const std::bad_any_cast&) { // 可能是聚合初始化返回的 vector,但标量只取第一个值 try { @@ -403,49 +542,60 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) { std::any_cast>(result); if (!init_values.empty()) { init = init_values[0]; + std::cerr << "[DEBUG] HandleLocalVariable: 从列表获取第一个初始化值" << std::endl; } else { init = builder_.CreateConstInt(0); + std::cerr << "[DEBUG] HandleLocalVariable: 初始化列表为空,使用0" << std::endl; } } catch (const std::bad_any_cast&) { init = builder_.CreateConstInt(0); + std::cerr << "[DEBUG] HandleLocalVariable: 无法解析初始化值类型,使用0" << std::endl; } } } else { init = builder_.CreateConstInt(0); + std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值结果,使用0" << std::endl; } } else { init = builder_.CreateConstInt(0); + std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值,使用0" << std::endl; } builder_.CreateStore(init, slot); - std::cerr << "[DEBUG] visitVarDef: 创建标量变量 " << varName + std::cerr << "[DEBUG] HandleLocalVariable: 创建局部变量 " << varName << ",初始值 " << (void*)init << std::endl; } + std::cerr << "[DEBUG] HandleLocalVariable: 局部变量处理完成" << std::endl; return {}; } std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) { + std::cerr << "[DEBUG] visitInitVal: 开始处理初始化值" << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法初始化值")); } // 如果是单个表达式 if (ctx->exp()) { + std::cerr << "[DEBUG] visitInitVal: 处理表达式初始化" << std::endl; return EvalExpr(*ctx->exp()); } // 如果是聚合初始化(花括号列表) else if (!ctx->initVal().empty()) { + std::cerr << "[DEBUG] visitInitVal: 处理聚合初始化" << std::endl; // 处理嵌套聚合初始化 return ProcessNestedInitVals(ctx); } + std::cerr << "[DEBUG] visitInitVal: 空初始化列表" << std::endl; // 空初始化列表 return std::vector{}; } // 新增:处理嵌套聚合初始化的辅助函数 std::vector IRGenImpl::ProcessNestedInitVals(SysYParser::InitValContext* ctx) { + std::cerr << "[DEBUG] ProcessNestedInitVals: 开始处理嵌套初始化值" << std::endl; std::vector all_values; for (auto* init_val : ctx->initVal()) { @@ -455,54 +605,163 @@ std::vector IRGenImpl::ProcessNestedInitVals(SysYParser::InitValCont // 尝试获取单个值 ir::Value* value = std::any_cast(result); all_values.push_back(value); + std::cerr << "[DEBUG] ProcessNestedInitVals: 获取到单个值" << std::endl; } catch (const std::bad_any_cast&) { try { // 尝试获取值列表(嵌套情况) std::vector nested_values = std::any_cast>(result); + std::cerr << "[DEBUG] ProcessNestedInitVals: 获取到嵌套值列表, 大小: " << nested_values.size() << std::endl; // 展平嵌套的值 all_values.insert(all_values.end(), nested_values.begin(), nested_values.end()); } catch (const std::bad_any_cast&) { // 未知类型 + std::cerr << "[ERROR] ProcessNestedInitVals: 不支持的初始化值类型" << std::endl; throw std::runtime_error( FormatError("irgen", "不支持的初始化值类型")); } } + } else { + std::cerr << "[DEBUG] ProcessNestedInitVals: 无初始化值结果" << std::endl; } } + std::cerr << "[DEBUG] ProcessNestedInitVals: 共获取 " << all_values.size() << " 个初始化值" << std::endl; return all_values; } int IRGenImpl::TryEvaluateConstInt(SysYParser::ConstExpContext* ctx) { + std::cerr << "[DEBUG] TryEvaluateConstInt: 开始求值常量表达式" << std::endl; if (!ctx) { std::cerr << "[DEBUG] TryEvaluateConstInt: ctx is null" << std::endl; return 0; } - try { - auto result = ctx->accept(this); - if (result.has_value()) { - try { - ir::Value* value = std::any_cast(result); - std::cerr << "[DEBUG] TryEvaluateConstInt: got IR value " << (void*)value << std::endl; - - // 尝试获取整数常量 - // 简化:检查是否是 ConstantInt - // 这里需要 IR 库的支持,暂时返回一个测试值 - return 16; // 暂时返回测试值 - } catch (const std::bad_any_cast& e) { - std::cerr << "[DEBUG] TryEvaluateConstInt: bad any_cast: " << e.what() << std::endl; - return 0; + // 直接访问常量表达式树,计算数值 + // 这里需要实现真正的常量求值逻辑 + // 简化版本:假设常量表达式是整数常量 + + if (ctx->addExp()) { + // 尝试从 addExp 求值 + return EvaluateConstAddExp(ctx->addExp()); + } + + return 0; +} + +// 添加辅助函数来求值常量表达式 +int IRGenImpl::EvaluateConstAddExp(SysYParser::AddExpContext* ctx) { + if (!ctx) return 0; + + // 如果没有左操作数,直接求值右操作数 + if (!ctx->addExp()) { + return EvaluateConstMulExp(ctx->mulExp()); + } + + int left = EvaluateConstAddExp(ctx->addExp()); + int right = EvaluateConstMulExp(ctx->mulExp()); + + if (ctx->AddOp()) { + return left + right; + } else if (ctx->SubOp()) { + return left - right; + } + + return 0; +} + +int IRGenImpl::EvaluateConstMulExp(SysYParser::MulExpContext* ctx) { + if (!ctx) return 0; + + // 如果没有左操作数,直接求值右操作数 + if (!ctx->mulExp()) { + return EvaluateConstUnaryExp(ctx->unaryExp()); + } + + int left = EvaluateConstMulExp(ctx->mulExp()); + int right = EvaluateConstUnaryExp(ctx->unaryExp()); + + if (ctx->MulOp()) { + return left * right; + } else if (ctx->DivOp()) { + return left / right; + } else if (ctx->QuoOp()) { + return left % right; + } + + return 0; +} + +int IRGenImpl::EvaluateConstUnaryExp(SysYParser::UnaryExpContext* ctx) { + if (!ctx) return 0; + + // 基本表达式(数字字面量) + if (ctx->primaryExp()) { + return EvaluateConstPrimaryExp(ctx->primaryExp()); + } + + // 一元运算 + if (ctx->unaryOp() && ctx->unaryExp()) { + int operand = EvaluateConstUnaryExp(ctx->unaryExp()); + std::string op = ctx->unaryOp()->getText(); + + if (op == "+") { + return operand; + } else if (op == "-") { + return -operand; + } else if (op == "!") { + return !operand; + } + } + + return 0; +} + +int IRGenImpl::EvaluateConstPrimaryExp(SysYParser::PrimaryExpContext* ctx) { + if (!ctx) return 0; + + // 处理数字字面量 + if (ctx->DECIMAL_INT()) { + return std::stoi(ctx->DECIMAL_INT()->getText()); + } + + if (ctx->HEX_INT()) { + std::string hex = ctx->HEX_INT()->getText(); + return std::stoi(hex, nullptr, 16); + } + + if (ctx->OCTAL_INT()) { + std::string oct = ctx->OCTAL_INT()->getText(); + return std::stoi(oct, nullptr, 8); + } + + if (ctx->ZERO()) { + return 0; + } + + // 处理括号表达式 + if (ctx->L_PAREN() && ctx->exp()) { + return EvaluateConstExp(ctx->exp()); + } + + // 常量标识符(引用其他常量) + if (ctx->lVal()) { + std::string const_name = ctx->lVal()->Ident()->getText(); + auto it = const_value_map_.find(const_name); + if (it != const_value_map_.end()) { + if (auto* const_int = dynamic_cast(it->second)) { + return const_int->GetValue(); } - } else { - std::cerr << "[DEBUG] TryEvaluateConstInt: result has no value" << std::endl; } - } catch (const std::exception& e) { - std::cerr << "[DEBUG] TryEvaluateConstInt: exception: " << e.what() << std::endl; + // 也可以从语义分析获取常量值 + // ... } - std::cerr << "[DEBUG] TryEvaluateConstInt: returning default value 10" << std::endl; - return 10; // 默认值 + return 0; } + +int IRGenImpl::EvaluateConstExp(SysYParser::ExpContext* ctx) { + if (!ctx || !ctx->addExp()) return 0; + return EvaluateConstAddExp(ctx->addExp()); +} \ No newline at end of file diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index 8b6e864..70d6296 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -120,7 +120,6 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) { // 2. 再通过 storage_map_ 找到该声明对应的栈槽位; // 3. 最后生成 load,把内存中的值读出来。 std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { - std::cout << "[DEBUG IRGEN] visitLVal: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx || !ctx->Ident()) { throw std::runtime_error(FormatError("irgen", "非法左值")); } @@ -128,7 +127,40 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { std::string varName = ctx->Ident()->getText(); std::cerr << "[DEBUG] visitLVal: " << varName << std::endl; - // 从语义分析获取变量定义 + // 优先检查是否是常量 + auto const_it = const_value_map_.find(varName); + if (const_it != const_value_map_.end()) { + // 常量直接返回值,不需要load + std::cerr << "[DEBUG] visitLVal: constant " << varName << std::endl; + return static_cast(const_it->second); + } + + // 检查全局常量 + auto const_global_it = const_global_map_.find(varName); + if (const_global_it != const_global_map_.end()) { + // 全局常量,需要load + ir::Value* ptr = const_global_it->second; + if (!ctx->exp().empty()) { + // 数组访问 + std::vector indices; + indices.push_back(builder_.CreateConstInt(0)); + for (auto* exp : ctx->exp()) { + ir::Value* index = EvalExpr(*exp); + indices.push_back(index); + } + ir::Value* elem_ptr = builder_.CreateGEP( + ptr, indices, module_.GetContext().NextTemp()); + return static_cast( + builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp())); + } else { + return static_cast( + builder_.CreateLoad(ptr, module_.GetContext().NextTemp())); + } + } + + // 不是常量,按正常变量处理 + // ... 原有的变量查找代码 ... + auto* decl = sema_.ResolveVarUse(ctx); ir::Value* ptr = nullptr; if (decl) { @@ -152,17 +184,39 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { } } + if (!ptr) { + auto it4 = local_var_map_.find(varName); + if (it4 != local_var_map_.end()) { + ptr = it4->second; + } + } + if (!ptr) { throw std::runtime_error( - FormatError("irgen", - "变量声明缺少存储槽位: " + varName)); + FormatError("irgen", "变量声明缺少存储槽位: " + varName)); } - return static_cast( - builder_.CreateLoad(ptr, module_.GetContext().NextTemp())); + // 检查是否有数组下标 + bool is_array_access = !ctx->exp().empty(); + if (is_array_access) { + std::vector indices; + indices.push_back(builder_.CreateConstInt(0)); + + for (auto* exp : ctx->exp()) { + ir::Value* index = EvalExpr(*exp); + indices.push_back(index); + } + + ir::Value* elem_ptr = builder_.CreateGEP( + ptr, indices, module_.GetContext().NextTemp()); + + return static_cast( + builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp())); + } else { + return static_cast( + builder_.CreateLoad(ptr, module_.GetContext().NextTemp())); + } } - - // 加法表达式 std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) { std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "") << std::endl; @@ -401,26 +455,41 @@ std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) { throw std::runtime_error(FormatError("irgen", "非法常量初始化值")); } - // 如果是单个表达式 + // 如果是单个常量表达式 if (ctx->constExp()) { try { - return ctx->constExp()->accept(this); + auto result = ctx->constExp()->accept(this); + if (result.has_value()) { + try { + ir::Value* value = std::any_cast(result); + // 尝试提取常量值 + if (auto* const_int = dynamic_cast(value)) { + return static_cast(const_int); + } else { + // 如果不是常量,尝试计算数值 + int int_val = TryEvaluateConstInt(ctx->constExp()); + return static_cast(builder_.CreateConstInt(int_val)); + } + } catch (const std::bad_any_cast&) { + int int_val = TryEvaluateConstInt(ctx->constExp()); + return static_cast(builder_.CreateConstInt(int_val)); + } + } + return static_cast(builder_.CreateConstInt(0)); } catch (const std::exception& e) { - std::cerr << "[WARNING] visitConstInitVal: 常量表达式求值失败: " << e.what() - << ",返回默认值0" << std::endl; + std::cerr << "[WARNING] visitConstInitVal: " << e.what() << std::endl; return static_cast(builder_.CreateConstInt(0)); } } // 如果是聚合初始化(花括号列表) else if (!ctx->constInitVal().empty()) { - // 处理嵌套聚合初始化 std::vector all_values; for (auto* init_val : ctx->constInitVal()) { auto result = init_val->accept(this); if (result.has_value()) { try { - // 尝试获取单个值 + // 尝试获取单个常量值 ir::Value* value = std::any_cast(result); all_values.push_back(value); } catch (const std::bad_any_cast&) { @@ -428,11 +497,9 @@ std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) { // 尝试获取值列表(嵌套情况) std::vector nested_values = std::any_cast>(result); - // 展平嵌套的值 all_values.insert(all_values.end(), nested_values.begin(), nested_values.end()); } catch (const std::bad_any_cast&) { - // 未知类型 throw std::runtime_error( FormatError("irgen", "不支持的常量初始化值类型")); } @@ -563,6 +630,15 @@ ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) { builder_.CreateStore(rhs, elem_ptr); } else { // 普通标量赋值 + // 调试输出指针类型 + std::cerr << "[DEBUG] base_ptr type: " << base_ptr->GetType() << std::endl; + std::cerr << "[DEBUG] rhs type: " << rhs->GetType()<< std::endl; + + // 如果 base_ptr 不是指针类型,可能需要特殊处理 + if (!base_ptr->GetType()->IsPtrInt32()) { + std::cerr << "[ERROR] base_ptr is not a pointer type!" << std::endl; + throw std::runtime_error("尝试存储到非指针类型"); + } builder_.CreateStore(rhs, base_ptr); } } else { diff --git a/src/irgen/IRGenStmt.cpp b/src/irgen/IRGenStmt.cpp index d5fe1af..056984a 100644 --- a/src/irgen/IRGenStmt.cpp +++ b/src/irgen/IRGenStmt.cpp @@ -268,43 +268,118 @@ IRGenImpl::BlockFlow IRGenImpl::HandleContinueStmt(SysYParser::StmtContext* ctx) } // 赋值语句(待实现) +// 赋值语句 +// 赋值语句 IRGenImpl::BlockFlow IRGenImpl::HandleAssignStmt(SysYParser::StmtContext* ctx) { + std::cout << "[DEBUG IRGEN] HandleAssignStmt: " << (ctx ? ctx->getText() : "") << std::endl; + if (!ctx || !ctx->lVal() || !ctx->exp()) { throw std::runtime_error(FormatError("irgen", "非法赋值语句")); } + // 计算右值 ir::Value* rhs = EvalExpr(*ctx->exp()); if (!rhs) { throw std::runtime_error(FormatError("irgen", "赋值 RHS 计算失败")); } - + auto* lval = ctx->lVal(); - auto* decl = sema_.ResolveVarUse(lval); - ir::Value* ptr = nullptr; - if (decl) { - auto it = storage_map_.find(decl); + std::string varName = lval->Ident()->getText(); + std::cerr << "[DEBUG] HandleAssignStmt: assigning to " << varName << std::endl; + + // 1. 检查是否为常量(不能给常量赋值) + auto* const_decl = sema_.ResolveConstUse(lval); + if (const_decl) { + throw std::runtime_error( + FormatError("irgen", "不能给常量赋值: " + varName)); + } + + // 2. 查找存储位置 + ir::Value* base_ptr = nullptr; + + // 2.1 尝试通过语义分析获取变量定义,并从 storage_map_ 查找 + auto* var_decl = sema_.ResolveVarUse(lval); + if (var_decl) { + auto it = storage_map_.find(var_decl); if (it != storage_map_.end()) { - ptr = it->second; + base_ptr = it->second; + std::cerr << "[DEBUG] HandleAssignStmt: found in storage_map_ for " << varName + << ", ptr = " << (void*)base_ptr << std::endl; } } - - if (!ptr && lval->Ident()) { - auto it = param_map_.find(lval->Ident()->getText()); - if (it != param_map_.end()) { - ptr = it->second; + + // 2.2 从参数映射查找(关键!) + if (!base_ptr) { + auto it2 = param_map_.find(varName); + if (it2 != param_map_.end()) { + base_ptr = it2->second; + std::cerr << "[DEBUG] HandleAssignStmt: found in param_map_ for " << varName + << ", ptr = " << (void*)base_ptr << std::endl; } - if (!ptr) { - auto it2 = global_map_.find(lval->Ident()->getText()); - if (it2 != global_map_.end()) { - ptr = it2->second; - } + } + + // 2.3 从全局变量映射查找 + if (!base_ptr) { + auto it3 = global_map_.find(varName); + if (it3 != global_map_.end()) { + base_ptr = it3->second; + std::cerr << "[DEBUG] HandleAssignStmt: found in global_map_ for " << varName + << ", ptr = " << (void*)base_ptr << std::endl; } } - - if (!ptr) { - throw std::runtime_error(FormatError("irgen", "赋值目标缺少存储槽位: " + lval->getText())); + + // 2.4 从局部变量映射查找(fallback) + if (!base_ptr) { + auto it4 = local_var_map_.find(varName); + if (it4 != local_var_map_.end()) { + base_ptr = it4->second; + std::cerr << "[DEBUG] HandleAssignStmt: found in local_var_map_ for " << varName + << ", ptr = " << (void*)base_ptr << std::endl; + } } - - builder_.CreateStore(rhs, ptr); + + // 如果还是找不到,才报错 + if (!base_ptr) { + throw std::runtime_error( + FormatError("irgen", "变量声明缺少存储槽位: " + varName)); + } + + // 3. 检查是否有数组下标 + auto exp_list = lval->exp(); + if (!exp_list.empty()) { + // 数组元素赋值 + std::vector indices; + indices.push_back(builder_.CreateConstInt(0)); + + for (auto* exp : exp_list) { + ir::Value* index = EvalExpr(*exp); + indices.push_back(index); + } + + ir::Value* elem_ptr = builder_.CreateGEP( + base_ptr, indices, module_.GetContext().NextTemp()); + + builder_.CreateStore(rhs, elem_ptr); + } else { + // 普通标量赋值 + std::cerr << "[DEBUG] HandleAssignStmt: scalar assignment to " << varName + << ", ptr = " << (void*)base_ptr + << ", rhs = " << (void*)rhs << std::endl; + // 在 HandleAssignStmt 中,存储前添加类型调试 + if (base_ptr && base_ptr->GetType()) { + + std::cerr << "[DEBUG] Is int32: " << base_ptr->GetType()->IsInt32() << std::endl; + std::cerr << "[DEBUG] Is float: " << base_ptr->GetType()->IsFloat() << std::endl; + std::cerr << "[DEBUG] Is ptr int32: " << base_ptr->GetType()->IsPtrInt32() << std::endl; + std::cerr << "[DEBUG] Is ptr float: " << base_ptr->GetType()->IsPtrFloat() << std::endl; + std::cerr << "[DEBUG] Is array: " << base_ptr->GetType()->IsArray() << std::endl; + } + if (rhs && rhs->GetType()) { + + std::cerr << "[DEBUG] Value is int32: " << rhs->GetType()->IsInt32() << std::endl; + } + builder_.CreateStore(rhs, base_ptr); + } + return BlockFlow::Continue; -} +} \ No newline at end of file diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index cb50416..cbedf1d 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -31,7 +31,6 @@ std::shared_ptr GetTypeFromBType(SysYParser::BTypeContext* ctx) { class SemaVisitor final : public SysYBaseVisitor { public: SemaVisitor() : table_() {} - std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override { if (!ctx) { throw std::runtime_error(FormatError("sema", "缺少编译单元")); @@ -1501,5 +1500,6 @@ private: SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit) { SemaVisitor visitor; comp_unit.accept(&visitor); - return visitor.TakeSemanticContext(); + SemanticContext ctx = visitor.TakeSemanticContext(); + return ctx; }