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

739 lines
26 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 <cmath>
#include <limits>
#include <stdexcept>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
namespace {
int ParseIntLiteral(const std::string& text) {
size_t parsed = 0;
long long value = std::stoll(text, &parsed, 0);
if (parsed != text.size()) {
throw std::runtime_error(FormatError("irgen", "非法整数字面量: " + text));
}
if (value < std::numeric_limits<int>::min() ||
value > std::numeric_limits<int>::max()) {
throw std::runtime_error(FormatError("irgen", "整数字面量越界: " + text));
}
return static_cast<int>(value);
}
double ParseFloatLiteral(const std::string& text) {
if (text.find("0x") == 0 || text.find("0X") == 0) {
// 手动解析十六进制浮点数常量
// 格式: 0x[hex_digits][.[hex_digits]][p|P[+|-][decimal_digits]]
std::string hex_part;
std::string exp_part;
size_t p_pos = text.find_first_of("pP");
if (p_pos != std::string::npos) {
hex_part = text.substr(0, p_pos);
exp_part = text.substr(p_pos + 1);
} else {
hex_part = text;
exp_part = "0";
}
// 解析十六进制部分
double mantissa = 0.0;
double frac = 0.0;
double frac_divisor = 1.0;
bool in_frac = false;
for (size_t i = 2; i < hex_part.size(); i++) {
char c = hex_part[i];
if (c == '.') {
in_frac = true;
continue;
}
int digit;
if (c >= '0' && c <= '9') {
digit = c - '0';
} else if (c >= 'a' && c <= 'f') {
digit = 10 + (c - 'a');
} else if (c >= 'A' && c <= 'F') {
digit = 10 + (c - 'A');
} else {
throw std::runtime_error(FormatError("irgen", "非法浮点字面量: " + text));
}
if (in_frac) {
frac_divisor *= 16.0;
frac += digit / frac_divisor;
} else {
mantissa = mantissa * 16.0 + digit;
}
}
mantissa += frac;
// 解析指数部分
int exponent = 0;
if (!exp_part.empty()) {
try {
exponent = std::stoi(exp_part);
} catch (...) {
throw std::runtime_error(FormatError("irgen", "非法浮点字面量: " + text));
}
}
return mantissa * std::pow(2.0, exponent);
} else {
// 解析十进制浮点数常量
char* end = nullptr;
double value = std::strtod(text.c_str(), &end);
if (end == text.c_str()) {
throw std::runtime_error(FormatError("irgen", "非法浮点字面量: " + text));
}
if (static_cast<size_t>(end - text.c_str()) != text.size()) {
throw std::runtime_error(FormatError("irgen", "非法浮点字面量: " + text));
}
return value;
}
}
void CollectInitExprs(SysYParser::InitValContext* init,
std::vector<SysYParser::ExpContext*>& out,
const std::vector<int>& dims,
size_t dim_idx = 0) {
if (!init) {
return;
}
if (init->exp()) {
out.push_back(init->exp());
return;
}
// 计算当前维度的大小
size_t current_dim_size = 1;
for (size_t i = dim_idx; i < dims.size(); ++i) {
current_dim_size *= dims[i];
}
size_t start_pos = out.size();
auto nested_inits = init->initVal();
if (dims.empty()) {
// 标量,直接处理
for (auto* nested : nested_inits) {
CollectInitExprs(nested, out, dims, dim_idx);
}
} else if (dim_idx < dims.size() - 1) {
// 多维数组,递归处理每个子数组
size_t sub_dim_size = 1;
for (size_t i = dim_idx + 1; i < dims.size(); ++i) {
sub_dim_size *= dims[i];
}
for (auto* nested : nested_inits) {
if (out.size() >= start_pos + current_dim_size) {
break;
}
CollectInitExprs(nested, out, dims, dim_idx + 1);
}
} else {
// 一维数组,直接展平所有初始化表达式
for (auto* nested : nested_inits) {
if (out.size() >= start_pos + current_dim_size) {
break;
}
CollectInitExprs(nested, out, dims, dim_idx);
}
}
// 确保不超过当前维度的大小
if (out.size() > start_pos + current_dim_size) {
// 截断超出的部分
out.resize(start_pos + current_dim_size);
}
// 补齐到当前维度大小
while (out.size() < start_pos + current_dim_size) {
out.push_back(nullptr);
}
}
void CollectConstInitExprs(SysYParser::ConstInitValContext* init,
std::vector<SysYParser::ConstExpContext*>& out,
const std::vector<int>& dims,
size_t dim_idx = 0) {
if (!init) {
return;
}
if (init->constExp()) {
out.push_back(init->constExp());
return;
}
// 计算当前维度的大小
size_t current_dim_size = 1;
for (size_t i = dim_idx; i < dims.size(); ++i) {
current_dim_size *= dims[i];
}
size_t start_pos = out.size();
auto nested_inits = init->constInitVal();
if (dims.empty()) {
// 标量,直接处理
for (auto* nested : nested_inits) {
CollectConstInitExprs(nested, out, dims, dim_idx);
}
} else if (dim_idx < dims.size() - 1) {
// 多维数组,递归处理每个子数组
size_t sub_dim_size = 1;
for (size_t i = dim_idx + 1; i < dims.size(); ++i) {
sub_dim_size *= dims[i];
}
for (auto* nested : nested_inits) {
if (out.size() >= start_pos + current_dim_size) {
break;
}
CollectConstInitExprs(nested, out, dims, dim_idx + 1);
}
} else {
// 一维数组,直接展平所有初始化表达式
for (auto* nested : nested_inits) {
if (out.size() >= start_pos + current_dim_size) {
break;
}
CollectConstInitExprs(nested, out, dims, dim_idx);
}
}
// 确保不超过当前维度的大小
if (out.size() > start_pos + current_dim_size) {
// 截断超出的部分
out.resize(start_pos + current_dim_size);
}
// 补齐到当前维度大小
while (out.size() < start_pos + current_dim_size) {
out.push_back(nullptr);
}
}
} // namespace
ir::AllocaInst* IRGenImpl::CreateEntryBlockAlloca(std::shared_ptr<ir::Type> elem_ty,
const std::string& name,
ir::Value* count) {
if (!func_ || func_->GetBlocks().empty()) {
throw std::runtime_error(FormatError("irgen", "无法在入口块分配栈空间:函数未定义或无基本块"));
}
auto* entry_block = func_->GetBlocks().front().get();
auto* alloca = entry_block->InsertAlloca<ir::AllocaInst>(elem_ty, name, count);
return alloca;
}
std::shared_ptr<ir::Type> IRGenImpl::ResolveBType(
SysYParser::BTypeContext* btype) const {
if (!btype) {
throw std::runtime_error(FormatError("irgen", "缺少基础类型"));
}
if (btype->Int()) {
return ir::Type::GetInt32Type();
}
if (btype->Float()) {
return ir::Type::GetFloat32Type();
}
throw std::runtime_error(FormatError("irgen", "当前仅支持 int/float 类型"));
}
std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
}
// 进入新的作用域,保存当前常量映射状态
const_value_history_.push_back(const_value_map_);
local_const_stack_.emplace_back();
bool terminated = false;
for (auto* item : ctx->blockItem()) {
if (item) {
if (VisitBlockItemResult(*item) == BlockFlow::Terminated) {
// 当前语法要求 return 为块内最后一条语句;命中后可停止生成。
terminated = true;
break;
}
}
}
// 退出作用域,恢复常量映射状态
const_value_map_ = const_value_history_.back();
const_value_history_.pop_back();
local_const_stack_.pop_back();
return terminated ? BlockFlow::Terminated : BlockFlow::Continue;
}
IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult(
SysYParser::BlockItemContext& item) {
return std::any_cast<BlockFlow>(item.accept(this));
}
std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少块内项"));
}
if (ctx->decl()) {
ctx->decl()->accept(this);
return BlockFlow::Continue;
}
if (ctx->stmt()) {
return ctx->stmt()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句或声明"));
}
// 变量声明的 IR 生成目前也是最小实现:
// - 先检查声明的基础类型,当前仅支持局部 int
// - 再把 Decl 中的变量定义交给 visitVarDef 继续处理。
//
// 和更完整的版本相比,这里还没有:
// - 一个 Decl 中多个变量定义的顺序处理;
// - const、数组、全局变量等不同声明形态
// - 更丰富的类型系统。
std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
}
if (ctx->constDecl()) {
auto* const_decl = ctx->constDecl();
if (!const_decl || !const_decl->bType()) {
throw std::runtime_error(FormatError("irgen", "非法常量声明"));
}
auto elem_ty = ResolveBType(const_decl->bType());
const bool is_float = elem_ty->IsFloat32();
for (auto* def : const_decl->constDef()) {
if (!def || !def->Ident()) {
continue;
}
const std::string name = def->Ident()->getText();
if (def->constExp().empty()) {
if (!is_float && def->constInitVal() && def->constInitVal()->constExp()) {
int const_value = EvalConstIntExpr(*def->constInitVal()->constExp());
if (!func_) {
// 只对全局整型常量进行常量折叠
const_value_map_[name] = const_value;
}
}
if (func_) {
// 局部常量:分配栈空间
auto* slot = builder_.CreateAlloca(elem_ty, module_.GetContext().NextTemp());
const_storage_map_[def] = slot;
ir::Value* init_elem = nullptr;
if (def->constInitVal() && def->constInitVal()->constExp()) {
init_elem = CastValueTo(
std::any_cast<ir::Value*>(def->constInitVal()->constExp()->accept(this)),
elem_ty);
} else {
init_elem = is_float ? static_cast<ir::Value*>(builder_.CreateConstFloat(0.0))
: static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
builder_.CreateStore(init_elem, slot);
} else {
// 全局常量:创建全局变量
if (is_float) {
double init_value = 0.0;
if (def->constInitVal() && def->constInitVal()->constExp()) {
init_value = EvalConstFloatExpr(*def->constInitVal()->constExp());
}
auto* global = module_.CreateGlobalF32(name, init_value);
const_global_storage_map_[def] = global;
} else {
int init_value = 0;
if (def->constInitVal() && def->constInitVal()->constExp()) {
init_value = EvalConstIntExpr(*def->constInitVal()->constExp());
}
auto* global = module_.CreateGlobalI32(name, init_value);
const_global_storage_map_[def] = global;
}
}
continue;
}
auto extents = EvalArrayExtents(def->constExp());
size_t total_extent = 1;
for (int extent : extents) {
total_extent *= static_cast<size_t>(extent);
}
const_array_extents_map_[def] = extents;
if (!func_) {
std::vector<SysYParser::ConstExpContext*> init_exprs;
bool has_init = false;
if (def->constInitVal()) {
has_init = true;
CollectConstInitExprs(def->constInitVal(), init_exprs, extents);
if (init_exprs.size() > total_extent) {
throw std::runtime_error(FormatError("irgen", "数组初始化元素过多"));
}
}
std::vector<int> init_values;
std::vector<double> init_float_values;
if (is_float) {
if (has_init) {
init_float_values.reserve(total_extent);
for (size_t index = 0; index < total_extent; ++index) {
if (index < init_exprs.size() && init_exprs[index] && init_exprs[index]->addExp()) {
double value = 0.0;
auto* cf = dynamic_cast<ir::ConstantFloat*>(CastValueTo(
std::any_cast<ir::Value*>(init_exprs[index]->addExp()->accept(this)),
ir::Type::GetFloat32Type()));
if (cf) {
value = cf->GetValue();
}
init_float_values.push_back(value);
} else {
init_float_values.push_back(0.0);
}
}
size_t trailing_zeros = 0;
while (trailing_zeros < init_float_values.size() && init_float_values[init_float_values.size() - 1 - trailing_zeros] == 0.0) {
trailing_zeros++;
}
if (trailing_zeros > 0) {
init_float_values.resize(init_float_values.size() - trailing_zeros);
}
auto* global = module_.CreateGlobalArrayF32(name, total_extent, init_float_values);
const_global_storage_map_[def] = global;
} else {
auto* global = module_.CreateGlobalArrayF32(name, total_extent, {});
const_global_storage_map_[def] = global;
}
} else {
if (has_init) {
init_values.reserve(total_extent);
for (size_t index = 0; index < total_extent; ++index) {
if (index < init_exprs.size() && init_exprs[index] && init_exprs[index]->addExp()) {
int value = 0;
auto* ci = dynamic_cast<ir::ConstantInt*>(CastValueTo(
std::any_cast<ir::Value*>(init_exprs[index]->addExp()->accept(this)),
ir::Type::GetInt32Type()));
if (ci) {
value = ci->GetValue();
}
init_values.push_back(value);
} else {
init_values.push_back(0);
}
}
size_t trailing_zeros = 0;
while (trailing_zeros < init_values.size() && init_values[init_values.size() - 1 - trailing_zeros] == 0) {
trailing_zeros++;
}
if (trailing_zeros > 0) {
init_values.resize(init_values.size() - trailing_zeros);
}
auto* global = module_.CreateGlobalArrayI32(name, total_extent, init_values);
const_global_storage_map_[def] = global;
} else {
auto* global = module_.CreateGlobalArrayI32(name, total_extent, {});
const_global_storage_map_[def] = global;
}
}
continue;
}
auto* slot =
builder_.CreateAlloca(elem_ty, module_.GetContext().NextTemp(),
builder_.CreateConstInt(static_cast<int>(total_extent)));
const_storage_map_[def] = slot;
std::vector<SysYParser::ConstExpContext*> init_exprs;
CollectConstInitExprs(def->constInitVal(), init_exprs, extents);
if (init_exprs.size() > total_extent) {
throw std::runtime_error(FormatError("irgen", "数组初始化元素过多"));
}
for (size_t index = 0; index < total_extent; ++index) {
auto* idx = builder_.CreateConstInt(static_cast<int>(index));
auto* ptr = builder_.CreateGEP(slot, idx, module_.GetContext().NextTemp());
ir::Value* init_elem = nullptr;
if (index < init_exprs.size() && init_exprs[index] && init_exprs[index]->addExp()) {
init_elem = CastValueTo(
std::any_cast<ir::Value*>(init_exprs[index]->addExp()->accept(this)),
elem_ty);
} else {
init_elem = is_float ? static_cast<ir::Value*>(builder_.CreateConstFloat(0.0))
: static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
builder_.CreateStore(init_elem, ptr);
}
}
return {};
}
if (!ctx->varDecl()) {
throw std::runtime_error(FormatError("irgen", "当前不支持 const 声明"));
}
ctx->varDecl()->accept(this);
return {};
}
std::any IRGenImpl::visitVarDecl(SysYParser::VarDeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法变量声明"));
}
if (!ctx->bType() || (!ctx->bType()->Int() && !ctx->bType()->Float())) {
throw std::runtime_error(
FormatError("irgen", "当前仅支持局部 int/float 变量声明"));
}
const auto& defs = ctx->varDef();
if (defs.empty()) {
throw std::runtime_error(FormatError("irgen", "非法变量声明"));
}
for (auto* def : defs) {
if (!def) {
throw std::runtime_error(FormatError("irgen", "非法变量声明"));
}
def->accept(this);
}
return {};
}
// 当前仍是教学用的最小版本,因此这里只支持:
// - 局部 int 变量;
// - 标量初始化;
// - 一个 VarDef 对应一个槽位。
std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量定义"));
}
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "变量声明缺少名称"));
}
const std::string name = ctx->Ident()->getText();
auto* var_decl = dynamic_cast<SysYParser::VarDeclContext*>(ctx->parent);
auto elem_ty = ResolveBType(var_decl ? var_decl->bType() : nullptr);
const bool is_float = elem_ty->IsFloat32();
if (name.empty()) {
throw std::runtime_error(FormatError("irgen", "变量声明缺少名称"));
}
const bool is_array = !ctx->constExp().empty();
std::vector<int> extents;
size_t total_extent = 1;
if (is_array) {
extents = EvalArrayExtents(ctx->constExp());
for (int extent : extents) {
total_extent *= static_cast<size_t>(extent);
}
array_extents_map_[ctx] = extents;
}
if (!func_) {
if (global_storage_map_.find(ctx) != global_storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成全局变量"));
}
if (is_array) {
std::vector<SysYParser::ExpContext*> init_exprs;
bool has_init = false;
if (auto* init_value = ctx->initVal()) {
has_init = true;
CollectInitExprs(init_value, init_exprs, extents);
if (init_exprs.size() > total_extent) {
throw std::runtime_error(FormatError("irgen", "数组初始化元素过多"));
}
}
std::vector<int> init_values;
std::vector<double> init_float_values;
if (is_float) {
if (has_init) {
init_float_values.reserve(total_extent);
for (size_t index = 0; index < total_extent; ++index) {
if (index < init_exprs.size() && init_exprs[index]) {
double value = 0.0;
auto* folded = EvalExpr(*init_exprs[index]);
auto* cf = dynamic_cast<ir::ConstantFloat*>(CastValueTo(folded, ir::Type::GetFloat32Type()));
if (cf) {
value = cf->GetValue();
}
init_float_values.push_back(value);
} else {
init_float_values.push_back(0.0);
}
}
size_t trailing_zeros = 0;
while (trailing_zeros < init_float_values.size() && init_float_values[init_float_values.size() - 1 - trailing_zeros] == 0.0) {
trailing_zeros++;
}
if (trailing_zeros > 0) {
init_float_values.resize(init_float_values.size() - trailing_zeros);
}
auto* global = module_.CreateGlobalArrayF32(name, total_extent, init_float_values);
global_storage_map_[ctx] = global;
} else {
auto* global = module_.CreateGlobalArrayF32(name, total_extent, {});
global_storage_map_[ctx] = global;
}
} else {
if (has_init) {
init_values.reserve(total_extent);
for (size_t index = 0; index < total_extent; ++index) {
if (index < init_exprs.size() && init_exprs[index]) {
int value = 0;
auto* folded = EvalExpr(*init_exprs[index]);
auto* ci = dynamic_cast<ir::ConstantInt*>(CastValueTo(folded, ir::Type::GetInt32Type()));
if (ci) {
value = ci->GetValue();
}
init_values.push_back(value);
} else {
init_values.push_back(0);
}
}
size_t trailing_zeros = 0;
while (trailing_zeros < init_values.size() && init_values[init_values.size() - 1 - trailing_zeros] == 0) {
trailing_zeros++;
}
if (trailing_zeros > 0) {
init_values.resize(init_values.size() - trailing_zeros);
}
auto* global = module_.CreateGlobalArrayI32(name, total_extent, init_values);
global_storage_map_[ctx] = global;
} else {
auto* global = module_.CreateGlobalArrayI32(name, total_extent, {});
global_storage_map_[ctx] = global;
}
}
return {};
}
int init = 0;
double init_float = 0.0;
if (auto* init_value = ctx->initVal()) {
if (!init_value->exp()) {
throw std::runtime_error(FormatError("irgen", "当前不支持聚合初始化"));
}
auto* folded = EvalExpr(*init_value->exp());
if (is_float) {
auto* cf = dynamic_cast<ir::ConstantFloat*>(CastValueTo(folded, ir::Type::GetFloat32Type()));
if (!cf) {
throw std::runtime_error(
FormatError("irgen", "全局浮点初始化必须是常量表达式"));
}
init_float = cf->GetValue();
} else {
auto* ci = dynamic_cast<ir::ConstantInt*>(CastValueTo(folded, ir::Type::GetInt32Type()));
if (!ci) {
throw std::runtime_error(
FormatError("irgen", "全局整型初始化必须是常量表达式"));
}
init = ci->GetValue();
}
}
auto* global =
is_float ? module_.CreateGlobalF32(name, init_float)
: module_.CreateGlobalI32(name, init);
global_storage_map_[ctx] = global;
return {};
}
// 检查是否已经在当前作用域中声明
if (storage_map_.find(ctx) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位"));
}
ir::Value* count = nullptr;
if (is_array) {
count = builder_.CreateConstInt(static_cast<int>(total_extent));
}
auto* slot = CreateEntryBlockAlloca(elem_ty, module_.GetContext().NextTemp(), count);
storage_map_[ctx] = slot;
if (is_array) {
std::vector<SysYParser::ExpContext*> init_exprs;
if (auto* init_value = ctx->initVal()) {
CollectInitExprs(init_value, init_exprs, extents);
if (init_exprs.size() > total_extent) {
throw std::runtime_error(FormatError("irgen", "数组初始化元素过多"));
}
// 对于小数组(<=10000元素直接生成完整初始化
if (total_extent <= 10000) {
for (size_t index = 0; index < total_extent; ++index) {
auto* idx = builder_.CreateConstInt(static_cast<int>(index));
auto* ptr = builder_.CreateGEP(slot, idx, module_.GetContext().NextTemp());
ir::Value* init_elem = nullptr;
if (index < init_exprs.size() && init_exprs[index]) {
init_elem = CastValueTo(EvalExpr(*init_exprs[index]), elem_ty);
} else {
init_elem = is_float ? static_cast<ir::Value*>(builder_.CreateConstFloat(0.0))
: static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
builder_.CreateStore(init_elem, ptr);
}
} else {
// 对于大数组,生成循环初始化零,然后初始化非零元素
auto* func = builder_.GetInsertBlock()->GetParent();
auto* loop_cond = func->CreateBlock("zero.init.cond");
auto* loop_body = func->CreateBlock("zero.init.body");
auto* loop_end = func->CreateBlock("zero.init.end");
auto* counter = builder_.CreateAlloca(ir::Type::GetInt32Type(), module_.GetContext().NextTemp());
builder_.CreateStore(builder_.CreateConstInt(0), counter);
builder_.CreateBr(loop_cond);
builder_.SetInsertPoint(loop_cond);
auto* counter_val = builder_.CreateLoad(counter, module_.GetContext().NextTemp());
auto* cond = builder_.CreateICmp(ir::Opcode::Lt, counter_val,
builder_.CreateConstInt(static_cast<int>(total_extent)),
module_.GetContext().NextTemp());
builder_.CreateCondBr(cond, loop_body, loop_end);
builder_.SetInsertPoint(loop_body);
auto* idx = builder_.CreateLoad(counter, module_.GetContext().NextTemp());
auto* ptr = builder_.CreateGEP(slot, idx, module_.GetContext().NextTemp());
auto* zero = is_float ? static_cast<ir::Value*>(builder_.CreateConstFloat(0.0))
: static_cast<ir::Value*>(builder_.CreateConstInt(0));
builder_.CreateStore(zero, ptr);
auto* new_counter = builder_.CreateAdd(builder_.CreateLoad(counter, module_.GetContext().NextTemp()),
builder_.CreateConstInt(1),
module_.GetContext().NextTemp());
builder_.CreateStore(new_counter, counter);
builder_.CreateBr(loop_cond);
builder_.SetInsertPoint(loop_end);
// 初始化非零元素
for (size_t index = 0; index < init_exprs.size(); ++index) {
if (init_exprs[index]) {
auto* idx = builder_.CreateConstInt(static_cast<int>(index));
auto* ptr = builder_.CreateGEP(slot, idx, module_.GetContext().NextTemp());
ir::Value* init_elem = CastValueTo(EvalExpr(*init_exprs[index]), elem_ty);
builder_.CreateStore(init_elem, ptr);
}
}
}
}
// 如果没有初始化列表,不生成任何初始化代码(局部变量默认不初始化)
return {};
}
ir::Value* init = nullptr;
if (auto* init_value = ctx->initVal()) {
if (!init_value->exp()) {
throw std::runtime_error(FormatError("irgen", "当前不支持聚合初始化"));
}
init = CastValueTo(EvalExpr(*init_value->exp()), elem_ty);
} else {
init = is_float ? static_cast<ir::Value*>(builder_.CreateConstFloat(0.0))
: static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
builder_.CreateStore(init, slot);
return {};
}