You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1156 lines
43 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "irgen/IRGen.h"
#include <stdexcept>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
// 表达式生成当前也只实现了很小的一个子集。
// 目前支持:
// - 整数字面量
// - 普通局部变量读取
// - 括号表达式
// - 二元加法
//
// 还未支持:
// - 减乘除与一元运算
// - 赋值表达式
// - 函数调用
// - 数组、指针、下标访问
// - 条件与比较表达式
// - ...
// 表达式生成
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
std::cerr << "[DEBUG IRGEN] EvalExpr: 开始处理表达式 " << expr.getText() << std::endl;
try {
auto result_any = expr.accept(this);
if (!result_any.has_value()) {
std::cerr << "[ERROR] EvalExpr: result_any has no value" << std::endl;
throw std::runtime_error("表达式求值结果为空");
}
try {
ir::Value* result = std::any_cast<ir::Value*>(result_any);
std::cerr << "[DEBUG] EvalExpr: success, result = " << (void*)result << std::endl;
return result;
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] EvalExpr: bad any_cast - " << e.what() << std::endl;
std::cerr << " Type info: " << result_any.type().name() << std::endl;
throw std::runtime_error(FormatError("irgen", "表达式求值返回了错误的类型"));
}
} catch (const std::exception& e) {
std::cerr << "[ERROR] Exception in EvalExpr: " << e.what() << std::endl;
throw;
}
}
ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
std::cerr << "[DEBUG IRGEN] EvalCond: 开始处理条件表达式 " << cond.getText() << std::endl;
return std::any_cast<ir::Value*>(cond.accept(this));
}
// 基本表达式:数字、变量、括号表达式
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitPrimaryExp: 开始处理基本表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
}
std::cerr << "[DEBUG] visitPrimaryExp" << std::endl;
// 处理数字字面量
if (ctx->DECIMAL_INT()) {
int value = std::stoi(ctx->DECIMAL_INT()->getText());
ir::Value* const_int = builder_.CreateConstInt(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant int " << value
<< " created as " << (void*)const_int << std::endl;
return static_cast<ir::Value*>(const_int);
}
if (ctx->HEX_FLOAT()) {
std::string hex_float_str = ctx->HEX_FLOAT()->getText();
float value = 0.0f;
try {
value = std::stof(hex_float_str);
} catch (const std::exception& e) {
std::cerr << "[WARNING] 无法解析十六进制浮点数: " << hex_float_str
<< "使用0.0代替" << std::endl;
value = 0.0f;
}
ir::Value* const_float = builder_.CreateConstFloat(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant hex float " << value
<< " created as " << (void*)const_float << std::endl;
return static_cast<ir::Value*>(const_float);
}
if (ctx->DEC_FLOAT()) {
std::string dec_float_str = ctx->DEC_FLOAT()->getText();
float value = 0.0f;
try {
value = std::stof(dec_float_str);
} catch (const std::exception& e) {
std::cerr << "[WARNING] 无法解析十进制浮点数: " << dec_float_str
<< "使用0.0代替" << std::endl;
value = 0.0f;
}
ir::Value* const_float = builder_.CreateConstFloat(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant dec float " << value
<< " created as " << (void*)const_float << std::endl;
return static_cast<ir::Value*>(const_float);
}
if (ctx->HEX_INT()) {
std::string hex = ctx->HEX_INT()->getText();
int value = std::stoi(hex, nullptr, 16);
ir::Value* const_int = builder_.CreateConstInt(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant hex int " << value
<< " created as " << (void*)const_int << std::endl;
return static_cast<ir::Value*>(const_int);
}
if (ctx->OCTAL_INT()) {
std::string oct = ctx->OCTAL_INT()->getText();
int value = std::stoi(oct, nullptr, 8);
ir::Value* const_int = builder_.CreateConstInt(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant octal int " << value
<< " created as " << (void*)const_int << std::endl;
return static_cast<ir::Value*>(const_int);
}
if (ctx->ZERO()) {
ir::Value* const_int = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] visitPrimaryExp: constant zero int created" << std::endl;
return static_cast<ir::Value*>(const_int);
}
// 处理变量
if (ctx->lVal()) {
std::cerr << "[DEBUG] visitPrimaryExp: visiting lVal" << std::endl;
return ctx->lVal()->accept(this);
}
// 处理括号表达式
if (ctx->L_PAREN() && ctx->exp()) {
std::cerr << "[DEBUG] visitPrimaryExp: visiting parenthesized expression" << std::endl;
return EvalExpr(*ctx->exp());
}
std::cerr << "[ERROR] visitPrimaryExp: unsupported primary expression type" << std::endl;
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
}
// 左值(变量)处理
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitLVal: 开始处理左值 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
std::string varName = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitLVal: " << varName << std::endl;
// 先检查语义分析中常量绑定
const SysYParser::ConstDefContext* const_decl = sema_.ResolveConstUse(ctx);
const Symbol* sym = nullptr;
if (const_decl) {
sym = symbol_table_.lookupByConstDef(const_decl);
if (!sym) {
sym = symbol_table_.lookupAll(varName);
}
} else {
sym = symbol_table_.lookup(varName);
}
// 如果是常量,直接返回常量值
if (sym && sym->kind == SymbolKind::Constant) {
std::cerr << "[DEBUG] visitLVal: 找到常量 " << varName << std::endl;
if (sym->IsScalarConstant()) {
if (sym->type->IsInt32()) {
ir::ConstantValue* const_val = builder_.CreateConstInt(sym->GetIntConstant());
return static_cast<ir::Value*>(const_val);
} else if (sym->type->IsFloat()) {
ir::ConstantValue* const_val = builder_.CreateConstFloat(sym->GetFloatConstant());
return static_cast<ir::Value*>(const_val);
}
} else if (sym->IsArrayConstant()) {
auto it = const_global_map_.find(varName);
if (it != const_global_map_.end()) {
ir::GlobalValue* global_array = it->second;
// 尝试获取类型信息,用于维度判断与下标线性化
auto* array_ty = dynamic_cast<ir::ArrayType*>(sym->type.get());
if (!array_ty) {
// 无法获取数组类型,退回返回全局对象
return static_cast<ir::Value*>(global_array);
}
size_t ndims = array_ty->GetDimensions().size();
// 有下标访问
if (!ctx->exp().empty()) {
size_t provided = ctx->exp().size();
// 完全索引(所有维度都有下标)——直接返回常量元素,不生成 Load
if (provided == ndims) {
std::vector<int> idxs;
idxs.reserve(provided);
for (auto* exp : ctx->exp()) {
ir::Value* v = EvalExpr(*exp);
if (!v || !v->IsConstant()) {
throw std::runtime_error(FormatError("irgen", "常量数组索引必须为常量整数: " + varName));
}
auto* ci = dynamic_cast<ir::ConstantInt*>(v);
if (!ci) {
throw std::runtime_error(FormatError("irgen", "常量数组索引非整型常量: " + varName));
}
idxs.push_back(ci->GetValue());
}
// 计算线性下标(行主序)
const auto& dims = array_ty->GetDimensions();
int flat = idxs[0];
for (size_t i = 1; i < ndims; ++i) {
flat = flat * dims[i] + idxs[i];
}
ir::ConstantValue* elem = global_array->GetArrayElement(static_cast<size_t>(flat));
return static_cast<ir::Value*>(elem);
}
// 部分索引:返回指针(不做 Load由上层按需处理
std::vector<ir::Value*> indices;
indices.push_back(builder_.CreateConstInt(0));
for (auto* exp : ctx->exp()) {
indices.push_back(EvalExpr(*exp));
}
return static_cast<ir::Value*>(
builder_.CreateGEP(global_array, indices, module_.GetContext().NextTemp()));
} else {
// 无下标,直接返回全局常量对象
return static_cast<ir::Value*>(global_array);
}
}
}
}
// 不是常量,按正常变量处理
auto* decl = sema_.ResolveVarUse(ctx);
ir::Value* ptr = nullptr;
if (decl) {
auto it = storage_map_.find(decl);
if (it != storage_map_.end()) {
ptr = it->second;
}
}
if (!ptr) {
auto it2 = param_map_.find(varName);
if (it2 != param_map_.end()) {
ptr = it2->second;
}
}
if (!ptr) {
auto it3 = global_map_.find(varName);
if (it3 != global_map_.end()) {
ptr = it3->second;
}
}
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));
}
// 检查是否有数组下标
bool is_array_access = !ctx->exp().empty();
if (is_array_access) {
// 收集下标表达式不含前导0
std::vector<ir::Value*> idx_vals;
for (auto* exp : ctx->exp()) {
ir::Value* index = EvalExpr(*exp);
idx_vals.push_back(index);
}
const Symbol* var_sym = sym;
if (!var_sym) {
var_sym = symbol_table_.lookup(varName);
}
if (!var_sym && decl) {
var_sym = symbol_table_.lookupByVarDef(decl);
}
if (!var_sym) {
var_sym = symbol_table_.lookupAll(varName);
}
std::vector<int> dims;
if (var_sym) {
if (var_sym->is_array_param && !var_sym->array_dims.empty()) {
dims = var_sym->array_dims;
} else if (var_sym->type && var_sym->type->IsArray()) {
auto* at = dynamic_cast<ir::ArrayType*>(var_sym->type.get());
if (at) dims = at->GetDimensions();
}
}
if (dims.empty() && ptr->GetType()->IsArray()) {
if (auto* at = dynamic_cast<ir::ArrayType*>(ptr->GetType().get())) {
dims = at->GetDimensions();
}
}
// 兜底:从语法树声明提取维度,避免作用域关闭后符号查询不完整。
if (dims.empty() && const_decl) {
auto* mutable_const_decl = const_cast<SysYParser::ConstDefContext*>(const_decl);
for (auto* cexp : mutable_const_decl->constExp()) {
dims.push_back(symbol_table_.EvaluateConstExp(cexp));
}
}
if (dims.empty() && decl) {
for (auto* cexp : decl->constExp()) {
dims.push_back(symbol_table_.EvaluateConstExp(cexp));
}
}
const bool is_partial_array_access =
!dims.empty() && idx_vals.size() < dims.size();
// 如果 base 是标量指针(例如局部扁平数组或数组参数),
// 需要把多维下标折合为单一线性下标,然后用一个索引进行 GEP。
if (ptr->GetType()->IsPtrInt32() || ptr->GetType()->IsPtrFloat()) {
// 如果没有维度信息,仍尝试用运行时算术合并下标(按后维乘积)
// flat = idx0 * (prod dims[1..]) + idx1 * (prod dims[2..]) + ...
ir::Value* flat = nullptr;
for (size_t i = 0; i < idx_vals.size(); ++i) {
ir::Value* term = idx_vals[i];
if (!term) continue;
// 计算乘数(后续维度乘积)
int mult = 1;
if (!dims.empty() && i + 1 < dims.size()) {
for (size_t j = i + 1; j < dims.size(); ++j) {
// 数组参数首维可能是 0表示省略不参与乘数。
if (dims[j] > 0) mult *= dims[j];
}
}
if (mult != 1) {
auto* mval = builder_.CreateConstInt(mult);
term = builder_.CreateMul(term, mval, module_.GetContext().NextTemp());
}
if (!flat) flat = term;
else flat = builder_.CreateAdd(flat, term, module_.GetContext().NextTemp());
}
if (!flat) flat = builder_.CreateConstInt(0);
// 使用单一索引创建 GEP
std::vector<ir::Value*> gep_indices = { flat };
ir::Value* elem_ptr = builder_.CreateGEP(ptr, gep_indices, module_.GetContext().NextTemp());
if (is_partial_array_access) {
return elem_ptr;
}
return static_cast<ir::Value*>(builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
}
std::vector<ir::Value*> indices;
// 标量指针T*使用单索引数组对象使用前导0进入首层。
if (ptr->GetType()->IsPtrInt32() || ptr->GetType()->IsPtrFloat()) {
for (auto* v : idx_vals) indices.push_back(v);
} else {
indices.push_back(builder_.CreateConstInt(0));
for (auto* v : idx_vals) indices.push_back(v);
}
ir::Value* elem_ptr = builder_.CreateGEP(ptr, indices, module_.GetContext().NextTemp());
if (is_partial_array_access) {
return elem_ptr;
}
return static_cast<ir::Value*>(builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
} else {
if ((sym && sym->is_array_param) ||
pointer_param_names_.find(varName) != pointer_param_names_.end() ||
heap_local_array_names_.find(varName) != heap_local_array_names_.end()) {
return ptr;
}
if (ptr->GetType()->IsArray()) {
return ptr;
}
return static_cast<ir::Value*>(builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
}
}
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitAddExp: 开始处理加法表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
// 如果没有 addExp(),说明是单个 mulExp()
if (!ctx->addExp()) {
return ctx->mulExp()->accept(this);
}
// 正确提取左操作数
auto left_any = ctx->addExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(left_any);
// 正确提取右操作数
auto right_any = ctx->mulExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left
<< ", type=" << (left->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)right
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) {
if (left->GetType()->IsFloat()) {
// left是floatright是int需要将right转换为float
right = builder_.CreateSIToFP(right, ir::Type::GetFloatType());
} else {
// right是floatleft是int需要将left转换为float
left = builder_.CreateSIToFP(left, ir::Type::GetFloatType());
}
}
// 根据操作符生成相应的指令
if (ctx->AddOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFAdd(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateAdd(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->SubOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFSub(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateSub(left, right, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知的加法操作符"));
}
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitMulExp: 开始处理乘法表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 如果是基本形式 UnaryExp
if (!ctx->mulExp()) {
return ctx->unaryExp()->accept(this);
}
// 提取左操作数
auto left_any = ctx->mulExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(left_any);
// 提取右操作数
auto right_any = ctx->unaryExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitMulExp: left=" << (void*)left
<< ", type=" << (left->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)right
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) {
if (left->GetType()->IsFloat()) {
// left是floatright是int需要将right转换为float
right = builder_.CreateSIToFP(right, ir::Type::GetFloatType());
} else {
// right是floatleft是int需要将left转换为float
left = builder_.CreateSIToFP(left, ir::Type::GetFloatType());
}
}
// 根据操作符生成指令
if (ctx->MulOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFMul(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateMul(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->DivOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFDiv(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateDiv(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->QuoOp()) {
// 取模运算:浮点数不支持取模,只支持整数
if (left->GetType()->IsFloat() || right->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("irgen", "浮点数不支持取模运算"));
}
return static_cast<ir::Value*>(
builder_.CreateMod(left, right, module_.GetContext().NextTemp()));
}
throw std::runtime_error(FormatError("irgen", "未知的乘法操作符"));
}
// 逻辑与
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitLAndExp: 开始处理逻辑与表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
if (!ctx->lAndExp()) {
return ctx->eqExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->eqExp()->accept(this));
auto to_bool = [&](ir::Value* v) -> ir::Value* {
if (v->GetType()->IsInt1()) {
return v;
}
if (v->GetType()->IsFloat()) {
return builder_.CreateFCmpONE(v, builder_.CreateConstFloat(0.0f),
module_.GetContext().NextTemp());
}
return builder_.CreateICmpNE(v, builder_.CreateConstInt(0),
module_.GetContext().NextTemp());
};
auto* left_bool = to_bool(left);
auto* right_bool = to_bool(right);
return static_cast<ir::Value*>(
builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp()));
}
// 逻辑或
std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitLOrExp: 开始处理逻辑或表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
if (!ctx->lOrExp()) {
return ctx->lAndExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lOrExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
auto to_bool = [&](ir::Value* v) -> ir::Value* {
if (v->GetType()->IsInt1()) {
return v;
}
if (v->GetType()->IsFloat()) {
return builder_.CreateFCmpONE(v, builder_.CreateConstFloat(0.0f),
module_.GetContext().NextTemp());
}
return builder_.CreateICmpNE(v, builder_.CreateConstInt(0),
module_.GetContext().NextTemp());
};
auto* left_bool = to_bool(left);
auto* right_bool = to_bool(right);
return static_cast<ir::Value*>(
builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp()));
}
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitExp: 开始处理表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式"));
return ctx->addExp()->accept(this);
}
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitCond: 开始处理条件 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
return ctx->lOrExp()->accept(this);
}
std::any IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitCallExp: 开始处理函数调用 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法函数调用"));
}
std::string funcName = ctx->Ident()->getText();
std::cout << "[DEBUG IRGEN] visitCallExp: 调用函数 " << funcName << std::endl;
// 查找函数对象
ir::Function* callee = module_.FindFunction(funcName);
// 如果没找到,可能是运行时函数还没声明,尝试动态声明
if (!callee) {
std::cout << "[DEBUG IRGEN] 函数 " << funcName << " 未找到,尝试动态声明" << std::endl;
// 根据函数名动态创建运行时函数声明
callee = CreateRuntimeFunctionDecl(funcName);
if (!callee) {
throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName));
}
}
// 收集实参
std::vector<ir::Value*> args;
if (ctx->funcRParams()) {
auto argList = ctx->funcRParams()->accept(this);
try {
args = std::any_cast<std::vector<ir::Value*>>(argList);
std::cout << "[DEBUG IRGEN] visitCallExp: 收集到 " << args.size() << " 个参数" << std::endl;
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] visitCallExp: 函数调用参数类型错误: " << e.what() << std::endl;
}
}
// 按形参类型修正实参(数组衰减为指针等)。
if (auto* fty = dynamic_cast<ir::FunctionType*>(callee->GetType().get())) {
const auto& param_tys = fty->GetParamTypes();
size_t n = std::min(param_tys.size(), args.size());
for (size_t i = 0; i < n; ++i) {
if (!args[i] || !param_tys[i]) continue;
// 数组实参传给指针形参时,执行数组到指针衰减。
if (args[i]->GetType()->IsArray() &&
(param_tys[i]->IsPtrInt32() || param_tys[i]->IsPtrFloat())) {
std::vector<ir::Value*> idx;
idx.push_back(builder_.CreateConstInt(0));
idx.push_back(builder_.CreateConstInt(0));
args[i] = builder_.CreateGEP(args[i], idx, module_.GetContext().NextTemp());
}
// 标量实参的隐式类型转换int <-> float
if (param_tys[i]->IsFloat() && args[i]->GetType()->IsInt32()) {
args[i] = builder_.CreateSIToFP(args[i], ir::Type::GetFloatType(),
module_.GetContext().NextTemp());
} else if (param_tys[i]->IsInt32() && args[i]->GetType()->IsFloat()) {
args[i] = builder_.CreateFPToSI(args[i], ir::Type::GetInt32Type(),
module_.GetContext().NextTemp());
}
}
}
// 生成调用指令
ir::Value* callResult = builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
// 如果函数返回 void返回一个默认值用于表达式上下文
if (callResult->GetType()->IsVoid()) {
// void 函数调用不产生值,但我们返回一个 0 常量以保持类型一致性
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
std::cout << "[DEBUG IRGEN] visitCallExp: 函数调用完成,返回值 " << (void*)callResult << std::endl;
return static_cast<ir::Value*>(callResult);
}
// 动态创建运行时函数声明的辅助函数
ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName) {
std::cerr << "[DEBUG IRGEN] CreateRuntimeFunctionDecl: 开始创建运行时函数声明 " << funcName << std::endl;
// 根据常见运行时函数名创建对应的函数类型
if (funcName == "getint" || funcName == "getch") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
}
else if (funcName == "putint" || funcName == "putch") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "getarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "putarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type(), ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "puts") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "starttime" || funcName == "stoptime") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}));
}
else if (funcName == "_sysy_starttime" || funcName == "_sysy_stoptime") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "getfloat") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetFloatType(), {}));
}
else if (funcName == "putfloat") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetFloatType()}));
}
else if (funcName == "getfarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetPtrFloatType()}));
}
else if (funcName == "putfarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type(), ir::Type::GetPtrFloatType()}));
}
else if (funcName == "memset") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetPtrInt32Type(),
{ir::Type::GetPtrInt32Type(),
ir::Type::GetInt32Type(),
ir::Type::GetInt32Type()}));
}
else if (funcName == "sysy_alloc_i32") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetPtrInt32Type(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "sysy_alloc_f32") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetPtrFloatType(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "sysy_free_i32") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "sysy_free_f32") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrFloatType()}));
}
else if (funcName == "sysy_zero_i32") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type()}));
}
else if (funcName == "sysy_zero_f32") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrFloatType(), ir::Type::GetInt32Type()}));
}
// 其他函数不支持动态创建
return nullptr;
}
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitUnaryExp: 开始处理一元表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法一元表达式"));
}
// 基本表达式
if (ctx->primaryExp()) {
return ctx->primaryExp()->accept(this);
}
// 函数调用
if (ctx->Ident()) {
return visitCallExp(ctx);
}
// 一元运算
if (ctx->unaryOp() && ctx->unaryExp()) {
auto* operand = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
std::string op = ctx->unaryOp()->getText();
if (op == "+") {
// +x 等价于 x
return operand;
} else if (op == "-") {
// -x 根据操作数类型选择整数或浮点减法
if (operand->GetType()->IsFloat()) {
// 浮点取负0.0 - x
ir::Value* zero_float = builder_.CreateConstFloat(0.0f);
return static_cast<ir::Value*>(
builder_.CreateFSub(zero_float, operand, module_.GetContext().NextTemp()));
} else {
// 整数取负0 - x
ir::Value* zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateSub(zero, operand, module_.GetContext().NextTemp()));
}
} else if (op == "!") {
// 逻辑非运算
// 先将值转换为bool与0比较
ir::Value* zero;
if (operand->GetType()->IsFloat()) {
zero = builder_.CreateConstFloat(0.0f);
// 浮点逻辑非x == 0.0
ir::Value* cmp = builder_.CreateFCmpOEQ(operand, zero, module_.GetContext().NextTemp());
// 将bool转换为int
return static_cast<ir::Value*>(
builder_.CreateZExt(cmp, ir::Type::GetInt32Type()));
} else {
zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateNot(operand, module_.GetContext().NextTemp()));
}
}
}
throw std::runtime_error(FormatError("irgen", "暂不支持的一元表达式形式"));
}
// 实现函数调用
std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitFuncRParams: 开始处理函数参数 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) return std::vector<ir::Value*>{};
std::vector<ir::Value*> args;
for (auto* exp : ctx->exp()) {
args.push_back(EvalExpr(*exp));
}
return args;
}
// visitConstExp - 处理常量表达式
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitConstExp: 开始处理常量表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->addExp()) {
throw std::runtime_error(FormatError("irgen", "非法常量表达式"));
}
auto result = ctx->addExp()->accept(this);
if (!result.has_value()) {
throw std::runtime_error(FormatError("irgen", "常量表达式求值失败"));
}
try {
return std::any_cast<ir::Value*>(result);
} catch (const std::bad_any_cast& e) {
throw std::runtime_error(FormatError("irgen",
"常量表达式返回类型错误: " + std::string(e.what())));
}
}
// visitConstInitVal - 处理常量初始化值
std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitConstInitVal: 开始处理常量初始化值 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法常量初始化值"));
}
// 如果是单个常量表达式
if (ctx->constExp()) {
return ctx->constExp()->accept(this);
}
// 如果是聚合初始化(花括号列表)
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()) {
throw std::runtime_error(FormatError("irgen", "常量初始化值求值失败"));
}
try {
// 尝试获取单个常量值
ir::Value* value = std::any_cast<ir::Value*>(result);
all_values.push_back(value);
} catch (const std::bad_any_cast&) {
try {
// 尝试获取值列表(嵌套情况)
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& e) {
throw std::runtime_error(FormatError("irgen",
"不支持的常量初始化值类型: " + std::string(e.what())));
}
}
}
return all_values;
}
// 空初始化列表
return std::vector<ir::Value*>{};
}
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitRelExp: 开始处理关系表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
}
if (ctx->relExp() && ctx->addExp()) {
auto left_any = ctx->relExp()->accept(this);
auto right_any = ctx->addExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitRelExp: left=" << (void*)lhs
<< ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)rhs
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) {
if (lhs->GetType()->IsFloat()) {
// lhs是floatrhs是int需要将rhs转换为float
rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType());
} else {
// rhs是floatlhs是int需要将lhs转换为float
lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType());
}
}
// 根据操作数和类型选择指令
if (ctx->LOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOLT(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->GOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOGT(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->LeOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOLE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->GeOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOGE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpGE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知关系运算符"));
}
if (ctx->addExp()) {
return ctx->addExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现"));
}
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
std::cerr << "[DEBUG IRGEN] visitEqExp: 开始处理相等表达式 " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
}
if (ctx->eqExp() && ctx->relExp()) {
auto left_any = ctx->eqExp()->accept(this);
auto right_any = ctx->relExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitEqExp: left=" << (void*)lhs
<< ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)rhs
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) {
if (lhs->GetType()->IsFloat()) {
// lhs是floatrhs是int需要将rhs转换为float
rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType());
} else {
// rhs是floatlhs是int需要将lhs转换为float
lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType());
}
}
// 根据操作符和类型选择指令
if (ctx->EqOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOEQ(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->NeOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpONE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpNE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知相等运算符"));
}
if (ctx->relExp()) {
return ctx->relExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
}
ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
std::cerr << "[DEBUG IRGEN] EvalAssign: 开始处理赋值语句 " << (ctx ? ctx->getText() : "<null>") << std::endl;
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->lVal() || !ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "非法赋值语句"));
}
// 计算右值
ir::Value* rhs = EvalExpr(*ctx->exp());
auto* lval = ctx->lVal();
std::string varName = lval->Ident()->getText();
// 首先尝试从语义分析获取变量定义
auto* var_decl = sema_.ResolveVarUse(lval);
if (var_decl) {
// 是变量赋值
// 从storage_map_获取存储位置
auto it = storage_map_.find(var_decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen", "变量声明缺少存储槽位: " + varName));
}
ir::Value* base_ptr = it->second;
auto convert_for_store = [&](ir::Value* value, ir::Value* ptr) -> ir::Value* {
if (ptr->GetType()->IsPtrFloat() && value->GetType()->IsInt32()) {
return builder_.CreateSIToFP(value, ir::Type::GetFloatType(),
module_.GetContext().NextTemp());
}
if (ptr->GetType()->IsPtrInt32() && value->GetType()->IsFloat()) {
return builder_.CreateFPToSI(value, ir::Type::GetInt32Type(),
module_.GetContext().NextTemp());
}
return value;
};
// 检查是否有数组下标
auto exp_list = lval->exp();
if (!exp_list.empty()) {
// 这是数组元素赋值需要生成GEP指令
std::vector<ir::Value*> indices;
// 标量指针参数T*不应添加前导0数组对象需要前导0。
if (!(base_ptr->GetType()->IsPtrInt32() || base_ptr->GetType()->IsPtrFloat())) {
indices.push_back(builder_.CreateConstInt(0));
}
// 添加用户提供的下标
for (auto* exp : exp_list) {
ir::Value* index = EvalExpr(*exp);
indices.push_back(index);
}
// 生成GEP指令获取元素地址
ir::Value* elem_ptr = builder_.CreateGEP(
base_ptr, indices, module_.GetContext().NextTemp());
// 生成store指令
rhs = convert_for_store(rhs, elem_ptr);
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() && !base_ptr->GetType()->IsPtrFloat()) {
std::cerr << "[ERROR] base_ptr is not a pointer type!" << std::endl;
throw std::runtime_error("尝试存储到非指针类型");
}
rhs = convert_for_store(rhs, base_ptr);
builder_.CreateStore(rhs, base_ptr);
}
} else {
// 尝试获取常量定义
auto* const_decl = sema_.ResolveConstUse(lval);
if (const_decl) {
// 尝试给常量赋值,这是错误的
throw std::runtime_error(
FormatError("irgen", "不能给常量赋值: " + varName));
} else {
throw std::runtime_error(
FormatError("irgen", "变量/常量使用缺少语义绑定: " + varName));
}
}
return rhs;
}