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.
nudt-compiler-cpp/src/irgen/IRGenDecl.cpp

516 lines
18 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"
namespace {
// 使用 LValContext 而不是 LValueContext
std::string GetLValueName(SysYParser::LValContext& lvalue) {
if (!lvalue.Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
return lvalue.Ident()->getText();
}
int TryGetConstInt(SysYParser::ConstExpContext* ctx) {
// 这里是一个简化的版本,实际上应该调用语义分析的常量求值
// 暂时假设所有常量表达式都是整数常量
// 实际实现需要更复杂的逻辑
// 简化为返回10
return 10;
}
} // namespace
// 注意visitBlock 已经在 IRGenFunc.cpp 中实现,这里不要重复定义
std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
}
// 处理 varDecl
if (auto* varDecl = ctx->varDecl()) {
// 检查类型
if (varDecl->bType() && varDecl->bType()->Int()) {
for (auto* varDef : varDecl->varDef()) {
varDef->accept(this);
}
} else {
throw std::runtime_error(FormatError("irgen", "当前仅支持 int 类型变量"));
}
}
// 处理 constDecl
if (ctx->constDecl()) {
auto* constDecl = ctx->constDecl();
if (constDecl->bType() && constDecl->bType()->Int()) {
for (auto* constDef : constDecl->constDef()) {
constDef->accept(this);
}
} else if (constDecl->bType() && constDecl->bType()->Float()) {
throw std::runtime_error(FormatError("irgen", "float常量暂未实现"));
} else {
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
}
}
return {};
}
std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法常量声明"));
}
std::cerr << "[DEBUG] visitConstDecl: processing constant declaration" << std::endl;
// 检查类型
if (ctx->bType()) {
if (ctx->bType()->Int()) {
// int 类型常量
for (auto* constDef : ctx->constDef()) {
if (constDef) {
constDef->accept(this);
}
}
} else if (ctx->bType()->Float()) {
// float 类型常量(暂不支持)
throw std::runtime_error(FormatError("irgen", "float常量暂未实现"));
} else {
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
}
} else {
throw std::runtime_error(FormatError("irgen", "常量声明缺少类型"));
}
return {};
}
// 实现常量定义
// 修改 visitConstDef 函数,使用 const_storage_map_
std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法常量定义"));
}
std::string const_name = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitConstDef: processing constant " << const_name << std::endl;
// 检查是否为数组
bool is_array = !ctx->constExp().empty();
if (is_array) {
// 数组常量处理
std::cerr << "[DEBUG] visitConstDef: array constant " << const_name << std::endl;
// 获取数组维度(简化处理)
int array_size = 10; // 默认数组大小
if (!ctx->constExp().empty()) {
// 尝试获取数组大小
// 简化假设第一个维度为10
array_size = 10;
}
// 分配数组存储(简化:为每个元素分配独立存储)
if (array_size > 100) {
throw std::runtime_error(FormatError("irgen", "数组常量大小太大"));
}
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);
}
// 处理初始化
if (auto* const_init_val = ctx->constInitVal()) {
if (const_init_val->constExp()) {
// 标量初始化(只初始化第一个元素)
try {
auto result = const_init_val->constExp()->accept(this);
if (result.has_value()) {
try {
ir::Value* init = std::any_cast<ir::Value*>(result);
builder_.CreateStore(init, 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& e) {
std::cerr << "[ERROR] visitConstDef: bad any_cast for array constant init: " << e.what() << std::endl;
throw std::runtime_error(FormatError("irgen", "常量数组初始化值类型错误"));
}
} else {
// 如果没有值全部初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstDef: 常量数组标量初始化失败: " << e.what()
<< "全部初始化为0" << std::endl;
// 初始化失败全部初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} else {
// 聚合初始化
auto initVals = const_init_val->constInitVal();
if (initVals.empty()) {
// 空初始化列表全部初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
} else {
// 有初始化值列表
int init_index = 0;
for (auto* init_val : initVals) {
if (init_index >= array_size) {
throw std::runtime_error(
FormatError("irgen", "常量数组初始化值太多,数组大小为" + std::to_string(array_size)));
}
if (init_val->constExp()) {
// 常量表达式初始化
try {
auto result = init_val->constExp()->accept(this);
if (result.has_value()) {
try {
ir::Value* val = std::any_cast<ir::Value*>(result);
builder_.CreateStore(val, element_slots[init_index]);
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] visitConstDef: bad any_cast for const array element: " << e.what() << std::endl;
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[init_index]);
}
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[init_index]);
}
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstDef: 常量数组元素初始化失败: " << e.what()
<< "使用默认值0" << std::endl;
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[init_index]);
}
} else {
// 嵌套的聚合初始化(暂不支持)
std::cerr << "[WARNING] visitConstDef: 常量数组嵌套聚合初始化暂不支持使用默认值0" << std::endl;
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[init_index]);
}
init_index++;
}
// 剩余元素初始化为0
for (int i = init_index; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
} else {
// 常量数组缺少初始值
throw std::runtime_error(FormatError("irgen", "常量数组缺少初始值"));
}
// 存储第一个元素的地址到 const_storage_map_
const_storage_map_[ctx] = element_slots[0]; // 修改这里
// 保存数组信息暂时不保存因为array_info_map_只用于变量
// ArrayInfo info;
// info.elements = element_slots;
// info.dimensions = {array_size};
// 暂时不保存,因为类型不匹配
std::cerr << "[DEBUG] visitConstDef: array constant " << const_name
<< " created with size " << 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();
if (const_init_val->constExp()) {
// 常量表达式求值
try {
auto result = const_init_val->constExp()->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;
// 标量常量也需要存储槽位,以便后续引用
// 创建alloca指令但立即存储常量值
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", "标量常量初始化值类型错误"));
}
}
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstDef: 标量常量表达式求值失败: " << e.what()
<< "使用默认值0" << std::endl;
}
// 如果求值失败使用默认值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);
return {};
} else {
// 标量常量的聚合初始化(大括号内只有一个值)
auto initVals = const_init_val->constInitVal();
if (initVals.empty()) {
// 空初始化使用默认值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);
return {};
} else if (initVals.size() == 1) {
// 单个元素的聚合初始化
auto* init_val = initVals[0];
if (init_val->constExp()) {
try {
auto result = init_val->constExp()->accept(this);
if (result.has_value()) {
try {
ir::Value* const_value = std::any_cast<ir::Value*>(result);
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 aggregate init: " << e.what() << std::endl;
}
}
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstDef: 标量常量聚合初始化失败: " << e.what()
<< "使用默认值0" << std::endl;
}
}
// 如果失败使用默认值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);
return {};
} else {
// 多个元素的聚合初始化对于标量常量是错误的
throw std::runtime_error(
FormatError("irgen", "标量常量聚合初始化只能有一个值"));
}
}
}
return {};
}
// 修改 visitVarDef 以支持简单的聚合初始化
std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量定义"));
}
// 使用 Ident() 而不是 lValue()
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "变量声明缺少名称"));
}
std::string varName = ctx->Ident()->getText();
if (storage_map_.find(ctx) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName));
}
bool is_array = !ctx->constExp().empty();
if (is_array) {
// 数组变量
// 获取数组维度(简化处理)
int array_size = 10; // 默认数组大小
if (!ctx->constExp().empty()) {
// 尝试获取数组大小(需要常量表达式求值)
// 简化假设第一个维度为10
array_size = 10;
// 尝试从常量表达式获取大小
// TODO: 这里需要常量表达式求值的支持
// 暂时使用简化处理
}
// 分配数组存储(简化:为每个元素分配独立存储)
if (array_size > 100) {
throw std::runtime_error(FormatError("irgen", "数组大小太大"));
}
std::vector<ir::Value*> element_slots;
for (int i = 0; i < array_size; i++) {
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + std::to_string(i));
element_slots.push_back(slot);
}
// 处理初始化
if (auto* initVal = ctx->initVal()) {
if (initVal->exp()) {
// 标量初始化(只初始化第一个元素)
ir::Value* init = EvalExpr(*initVal->exp());
builder_.CreateStore(init, element_slots[0]);
// 其他元素初始化为0
for (int i = 1; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
} else {
// 聚合初始化 - 现在实现简单的聚合初始化
auto initVals = initVal->initVal();
if (initVals.empty()) {
// 空初始化列表全部初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
} else {
// 有初始化值列表
int init_index = 0;
for (auto* init_val : initVals) {
if (init_index >= array_size) {
throw std::runtime_error(
FormatError("irgen", "初始化值太多,数组大小为" + std::to_string(array_size)));
}
if (init_val->exp()) {
// 简单表达式初始化
ir::Value* val = EvalExpr(*init_val->exp());
builder_.CreateStore(val, element_slots[init_index]);
} else {
// 嵌套的聚合初始化(暂不支持)
throw std::runtime_error(
FormatError("irgen", "嵌套聚合初始化暂未实现"));
}
init_index++;
}
// 剩余元素初始化为0
for (int i = init_index; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
} else {
// 无初始化所有元素初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
// 存储第一个元素的地址
storage_map_[ctx] = element_slots[0];
// 保存数组信息
ArrayInfo info;
info.elements = element_slots;
info.dimensions = {array_size};
array_info_map_[ctx] = info;
} else {
// 标量变量
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[ctx] = slot;
ir::Value* init = nullptr;
if (auto* initVal = ctx->initVal()) {
if (initVal->exp()) {
init = EvalExpr(*initVal->exp());
} else {
// 聚合初始化(对于标量,大括号内应该只有一个值)
auto initVals = initVal->initVal();
if (initVals.empty()) {
init = builder_.CreateConstInt(0);
} else if (initVals.size() == 1) {
// 递归处理嵌套的初始化值
auto* inner_init_val = initVals[0];
if (inner_init_val->exp()) {
init = EvalExpr(*inner_init_val->exp());
} else {
// 多层嵌套暂不支持
throw std::runtime_error(
FormatError("irgen", "标量变量的多层嵌套初始化暂不支持"));
}
} else {
throw std::runtime_error(
FormatError("irgen", "标量变量聚合初始化只能有一个值"));
}
}
} else {
init = builder_.CreateConstInt(0);
}
builder_.CreateStore(init, slot);
}
return {};
}
// 修改后的 visitInitVal支持简单的聚合初始化
std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法初始化值"));
}
// 如果是单个表达式
if (ctx->exp()) {
return EvalExpr(*ctx->exp());
}
// 如果是聚合初始化(花括号列表)
else if (!ctx->initVal().empty()) {
// 返回一个 vector包含所有初始化值
std::vector<ir::Value*> initValues;
for (auto* initVal : ctx->initVal()) {
// 递归处理每个初始化值
auto result = initVal->accept(this);
if (result.has_value()) {
try {
ir::Value* value = std::any_cast<ir::Value*>(result);
initValues.push_back(value);
} catch (const std::bad_any_cast&) {
// 可能返回的是 vector对于嵌套数组初始化
// 简化:我们暂时只支持一维数组
throw std::runtime_error(
FormatError("irgen", "暂不支持多维数组初始化"));
}
}
}
// 返回初始化值列表
return initValues;
}
throw std::runtime_error(FormatError("irgen", "不支持的初始化值形式"));
}