<feature/ir>全局变量及局部变量区分,支持整型常量

feature/sem
LuoHello 2 weeks ago
parent 728de089ff
commit 700bbb4e3b

@ -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<ArrayType> ty,
std::vector<ConstantValue*> elements);
// 获取零常量(按类型缓存)
ConstantZero* GetZeroConstant(std::shared_ptr<Type> ty);
// 获取聚合类型的零常量
ConstantAggregateZero* GetAggregateZero(std::shared_ptr<Type> ty);
std::string NextTemp();
private:
std::unordered_map<int, std::unique_ptr<ConstantInt>> const_ints_;
// 浮点常量:使用整数表示浮点数位模式作为键(避免浮点精度问题)
std::unordered_map<uint32_t, std::unique_ptr<ConstantFloat>> const_floats_;
// 零常量缓存(按类型指针)
std::unordered_map<Type*, std::unique_ptr<ConstantZero>> zero_constants_;
std::unordered_map<Type*, std::unique_ptr<ConstantAggregateZero>> aggregate_zeros_;
// 数组常量简单存储,不去重(因为数组常量通常组合多样,去重成本高)
std::vector<std::unique_ptr<ConstantArray>> 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<Type> ty, float v);
float GetValue() const { return value_; }
private:
float value_{};
};
// ConstantArray - 数组常量
class ConstantArray : public ConstantValue {
public:
// 构造函数:接收数组类型和常量元素列表
ConstantArray(std::shared_ptr<ArrayType> ty, std::vector<ConstantValue*> elements);
// 获取元素数量
size_t GetNumElements() const { return elements_.size(); }
// 获取指定索引的元素
ConstantValue* GetElement(size_t index) const { return elements_[index]; }
// 获取所有元素
const std::vector<ConstantValue*>& GetElements() const { return elements_; }
// 验证常量数组的类型是否正确
bool IsValid() const;
private:
std::vector<ConstantValue*> elements_;
};
// ConstantZero - 零常量(用于零初始化)
class ConstantZero : public ConstantValue {
public:
explicit ConstantZero(std::shared_ptr<Type> ty);
// 工厂方法:创建特定类型的零常量
static std::unique_ptr<ConstantZero> GetZero(std::shared_ptr<Type> ty);
};
// ConstantAggregateZero - 聚合类型的零常量(数组、结构体等)
class ConstantAggregateZero : public ConstantValue {
public:
explicit ConstantAggregateZero(std::shared_ptr<Type> ty);
// 获取聚合类型
std::shared_ptr<Type> GetAggregateType() const { return GetType(); }
// 工厂方法:创建聚合类型的零常量
static std::unique_ptr<ConstantAggregateZero> GetZero(std::shared_ptr<Type> 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<ConstantValue*> initializer_; // 初始化值列表
bool is_constant_ = false; // 是否为常量如const变量
bool is_extern_ = false; // 是否为外部声明
public:
GlobalValue(std::shared_ptr<Type> ty, std::string name);
// 初始化器相关 - 使用 ConstantValue*
void SetInitializer(ConstantValue* init);
void SetInitializer(const std::vector<ConstantValue*>& init);
const std::vector<ConstantValue*>& 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<ArrayType*>(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<ArrayType> ty,
std::vector<ConstantValue*> elements); // 新增
ConstantZero* CreateZeroConstant(std::shared_ptr<Type> 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

@ -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<SysYParser::VarDefContext*, ir::Value*> storage_map_;
std::unordered_map<SysYParser::ConstDefContext*, ir::Value*> const_storage_map_; // 新增
// 按变量名快速查找(用于 LVal 等场景)
std::unordered_map<std::string, ir::Value*> local_var_map_; // 局部变量
std::unordered_map<std::string, ir::GlobalValue*> global_map_; // 全局变量
std::unordered_map<std::string, ir::Value*> param_map_; // 函数参数
// 常量映射:常量名 -> 常量值(标量常量)
std::unordered_map<std::string, ir::ConstantValue*> const_value_map_;
// 全局常量映射:常量名 -> 全局变量(数组常量)
std::unordered_map<std::string, ir::GlobalValue*> const_global_map_;
// 原有的常量存储映射(用于兼容)
std::unordered_map<antlr4::ParserRuleContext*, ir::Value*> const_storage_map_;
std::unordered_map<SysYParser::VarDefContext*, ArrayInfo> array_info_map_;
ir::Value* EvalAssign(SysYParser::StmtContext* ctx);
std::unordered_map<std::string, ir::Value*> param_map_;// 函数参数映射key 是参数名value 是对应的 IR 值(通常是 AllocaInst 或 Function 参数)
std::unordered_map<std::string, ir::Value*> 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<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,

@ -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"

@ -1,6 +1,8 @@
// 管理基础类型、整型常量池和临时名生成。
#include "ir/IR.h"
// ir/IR.cpp
#include "ir/IR.h"
#include <cstring> // for memcpy
#include <sstream>
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<ConstantFloat>(float_ty, v);
auto* ptr = constant.get();
const_floats_[key] = std::move(constant);
return ptr;
}
// 新增:创建数组常量
ConstantArray* Context::GetConstArray(std::shared_ptr<ArrayType> ty,
std::vector<ConstantValue*> elements) {
auto constant = std::make_unique<ConstantArray>(ty, std::move(elements));
auto* ptr = constant.get();
const_arrays_.push_back(std::move(constant));
return ptr;
}
// 新增:获取零常量
ConstantZero* Context::GetZeroConstant(std::shared_ptr<Type> ty) {
auto it = zero_constants_.find(ty.get());
if (it != zero_constants_.end()) {
return it->second.get();
}
auto constant = std::make_unique<ConstantZero>(ty);
auto* ptr = constant.get();
zero_constants_[ty.get()] = std::move(constant);
return ptr;
}
// 新增:获取聚合类型的零常量
ConstantAggregateZero* Context::GetAggregateZero(std::shared_ptr<Type> ty) {
auto it = aggregate_zeros_.find(ty.get());
if (it != aggregate_zeros_.end()) {
return it->second.get();
}
auto constant = std::make_unique<ConstantAggregateZero>(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

@ -1,11 +1,121 @@
// GlobalValue 占位实现:
// - 具体的全局初始化器、打印和链接语义需要自行补全
// ir/GlobalValue.cpp
#include "ir/IR.h"
#include <stdexcept>
namespace ir {
GlobalValue::GlobalValue(std::shared_ptr<Type> 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<Type> 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<ArrayType*>(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<ConstantValue*>& init) {
if (init.empty()) {
return;
}
// 获取实际的值类型
std::shared_ptr<Type> 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<ArrayType*>(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

@ -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<ArrayType> ty,
std::vector<ConstantValue*> elements) {
return ctx_.GetConstArray(ty, std::move(elements));
}
ConstantZero* IRBuilder::CreateZeroConstant(std::shared_ptr<Type> ty) {
return ctx_.GetZeroConstant(ty);
}
BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {

@ -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<const ConstantInt*>(constant)) {
os << const_int->GetValue();
}
else if (auto* const_float = dynamic_cast<const ConstantFloat*>(constant)) {
os << const_float->GetValue();
}
else if (auto* const_array = dynamic_cast<const ConstantArray*>(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<const ConstantZero*>(constant)) {
os << "zero";
}
else if (auto* agg_zero = dynamic_cast<const ConstantAggregateZero*>(constant)) {
os << "zeroinitializer";
}
}
} // namespace ir

@ -29,7 +29,21 @@ const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
GlobalValue* Module::CreateGlobal(const std::string& name,
std::shared_ptr<Type> ty) {
globals_.push_back(std::make_unique<GlobalValue>(ty, name));
// 对于标量类型,自动转换为指针类型
std::shared_ptr<Type> 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<GlobalValue>(global_ty, name));
return globals_.back().get();
}

@ -82,4 +82,59 @@ Argument::Argument(std::shared_ptr<Type> ty, std::string name)
ConstantInt::ConstantInt(std::shared_ptr<Type> ty, int v)
: ConstantValue(std::move(ty), ""), value_(v) {}
// ConstantFloat 实现
ConstantFloat::ConstantFloat(std::shared_ptr<Type> ty, float v)
: ConstantValue(ty, ""), value_(v) {
if (!ty->IsFloat()) {
throw std::runtime_error("ConstantFloat requires Float type");
}
}
// ConstantArray 实现
ConstantArray::ConstantArray(std::shared_ptr<ArrayType> ty,
std::vector<ConstantValue*> 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<ArrayType*>(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<Type> ty)
: ConstantValue(ty, "zero") {
// 零常量可以用于任何类型
}
std::unique_ptr<ConstantZero> ConstantZero::GetZero(std::shared_ptr<Type> ty) {
return std::make_unique<ConstantZero>(ty);
}
// ConstantAggregateZero 实现
ConstantAggregateZero::ConstantAggregateZero(std::shared_ptr<Type> ty)
: ConstantValue(ty, "zero") {
if (!ty->IsArray()) {
throw std::runtime_error("ConstantAggregateZero requires aggregate type");
}
}
std::unique_ptr<ConstantAggregateZero> ConstantAggregateZero::GetZero(std::shared_ptr<Type> ty) {
return std::make_unique<ConstantAggregateZero>(ty);
}
} // namespace ir

@ -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<int> 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<ir::Value*> 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<ir::ConstantValue*> init_consts;
if (auto* const_init_val = ctx->constInitVal()) {
// 获取初始化值
auto result = const_init_val->accept(this);
if (result.has_value()) {
try {
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
// 检查初始化值数量
if (init_values.size() > static_cast<size_t>(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<size_t>(array_size); i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
auto init_vec = std::any_cast<std::vector<ir::Value*>>(result);
for (auto* val : init_vec) {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(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<ir::Value*>(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<ir::Value*>(result);
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(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<size_t>(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<ir::Value*>(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<int> 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<ir::ConstantValue*> 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<std::vector<ir::Value*>>(result);
std::cerr << "[DEBUG] HandleGlobalVariable: 获取到初始化值列表, 大小: " << init_vec.size() << std::endl;
for (auto* val : init_vec) {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(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<ir::Value*>(result);
std::cerr << "[DEBUG] HandleGlobalVariable: 获取到单个初始化值" << std::endl;
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(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<size_t>(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<SysYParser::ConstDefContext*>(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<ir::Value*>(result);
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(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<SysYParser::ConstDefContext*>(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<int> 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<ir::Value*> 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<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
std::cerr << "[DEBUG] HandleLocalVariable: 获取到初始化值列表, 大小: " << init_values.size() << std::endl;
// 检查初始化值数量
if (init_values.size() > static_cast<size_t>(total_size)) {
// 对于多维数组,这可能是正常的
// 我们打印警告但继续执行
std::cerr << "[WARNING] visitVarDef: 初始化值(" << init_values.size()
<< ")超过数组总大小(" << total_size
<< "),只初始化前" << total_size << "个元素" << std::endl;
// 只初始化能容纳的部分
for (size_t i = 0; i < static_cast<size_t>(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<size_t>(total_size); i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
// 初始化数组元素
for (size_t i = 0; i < init_values.size() && i < static_cast<size_t>(total_size); i++) {
builder_.CreateStore(init_values[i], element_slots[i]);
}
// 剩余元素初始化为0
for (size_t i = init_values.size(); i < static_cast<size_t>(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<ir::Value*>(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<ir::Value*>(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<std::vector<ir::Value*>>(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<ir::Value*>{};
}
// 新增:处理嵌套聚合初始化的辅助函数
std::vector<ir::Value*> IRGenImpl::ProcessNestedInitVals(SysYParser::InitValContext* ctx) {
std::cerr << "[DEBUG] ProcessNestedInitVals: 开始处理嵌套初始化值" << std::endl;
std::vector<ir::Value*> all_values;
for (auto* init_val : ctx->initVal()) {
@ -455,54 +605,163 @@ std::vector<ir::Value*> IRGenImpl::ProcessNestedInitVals(SysYParser::InitValCont
// 尝试获取单个值
ir::Value* value = std::any_cast<ir::Value*>(result);
all_values.push_back(value);
std::cerr << "[DEBUG] ProcessNestedInitVals: 获取到单个值" << std::endl;
} catch (const std::bad_any_cast&) {
try {
// 尝试获取值列表(嵌套情况)
std::vector<ir::Value*> nested_values =
std::any_cast<std::vector<ir::Value*>>(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<ir::Value*>(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<ir::ConstantInt*>(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());
}

@ -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() : "<null>") << 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<ir::Value*>(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<ir::Value*> 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<ir::Value*>(
builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
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<ir::Value*>(
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
// 检查是否有数组下标
bool is_array_access = !ctx->exp().empty();
if (is_array_access) {
std::vector<ir::Value*> 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<ir::Value*>(
builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
}
}
// 加法表达式
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "<null>") << 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<ir::Value*>(result);
// 尝试提取常量值
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(value)) {
return static_cast<ir::Value*>(const_int);
} else {
// 如果不是常量,尝试计算数值
int int_val = TryEvaluateConstInt(ctx->constExp());
return static_cast<ir::Value*>(builder_.CreateConstInt(int_val));
}
} catch (const std::bad_any_cast&) {
int int_val = TryEvaluateConstInt(ctx->constExp());
return static_cast<ir::Value*>(builder_.CreateConstInt(int_val));
}
}
return static_cast<ir::Value*>(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<ir::Value*>(builder_.CreateConstInt(0));
}
}
// 如果是聚合初始化(花括号列表)
else if (!ctx->constInitVal().empty()) {
// 处理嵌套聚合初始化
std::vector<ir::Value*> 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<ir::Value*>(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<ir::Value*> nested_values =
std::any_cast<std::vector<ir::Value*>>(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 {

@ -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() : "<null>") << 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<ir::Value*> 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;
}
}

@ -31,7 +31,6 @@ std::shared_ptr<ir::Type> 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;
}

Loading…
Cancel
Save