|
|
#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", "不支持的初始化值形式"));
|
|
|
}
|
|
|
|
|
|
|