[midend-mem2reg]修复assignstmt对lvalue的错误解析(lvaue会被exp解释为值,而被assign解释为地址)
This commit is contained in:
@@ -450,44 +450,79 @@ std::any SysYIRGenerator::visitBlockStmt(SysYParser::BlockStmtContext *ctx) {
|
||||
std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
||||
auto lVal = ctx->lValue();
|
||||
std::string name = lVal->Ident()->getText();
|
||||
std::vector<Value *> dims;
|
||||
for (const auto &exp : lVal->exp()) {
|
||||
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
|
||||
Value* LValue = nullptr;
|
||||
Value* variable = module->getVariable(name); // 左值
|
||||
|
||||
vector<Value *> indices;
|
||||
if (lVal->exp().size() > 0) {
|
||||
// 如果有下标,访问表达式获取下标值
|
||||
for (const auto &exp : lVal->exp()) {
|
||||
Value* indexValue = std::any_cast<Value *>(visitExp(exp));
|
||||
indices.push_back(indexValue);
|
||||
}
|
||||
}
|
||||
if (indices.empty()) {
|
||||
// variable 本身就是指向标量的指针 (e.g., int* %a)
|
||||
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
|
||||
LValue = variable;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 对于数组或多维数组的左值处理
|
||||
// 需要获取 GEP 地址
|
||||
Value* gepBasePointer = nullptr;
|
||||
std::vector<Value*> gepIndices;
|
||||
if (AllocaInst *alloc = dynamic_cast<AllocaInst *>(variable)) {
|
||||
Type* allocatedType = alloc->getType()->as<PointerType>()->getBaseType();
|
||||
if (allocatedType->isPointer()) {
|
||||
gepBasePointer = builder.createLoadInst(alloc);
|
||||
gepIndices = indices;
|
||||
} else {
|
||||
gepBasePointer = alloc;
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
gepIndices.insert(gepIndices.end(), indices.begin(), indices.end());
|
||||
}
|
||||
} else if (GlobalValue *glob = dynamic_cast<GlobalValue *>(variable)) {
|
||||
// 情况 B: 全局变量 (GlobalValue)
|
||||
gepBasePointer = glob;
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
gepIndices.insert(gepIndices.end(), indices.begin(), indices.end());
|
||||
} else if (ConstantVariable *constV = dynamic_cast<ConstantVariable *>(variable)) {
|
||||
gepBasePointer = constV;
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
gepIndices.insert(gepIndices.end(), indices.begin(), indices.end());
|
||||
}
|
||||
// 左值为地址
|
||||
LValue = getGEPAddressInst(gepBasePointer, gepIndices);
|
||||
}
|
||||
|
||||
auto variable = module->getVariable(name); // 获取 AllocaInst 或 GlobalValue
|
||||
Value* value = std::any_cast<Value *>(visitExp(ctx->exp())); // 右值
|
||||
|
||||
Type* targetElementType = variable->getType(); // 从基指针指向的类型开始
|
||||
Value* RValue = std::any_cast<Value *>(visitExp(ctx->exp())); // 右值
|
||||
|
||||
//根据 dims 确定最终元素的类型
|
||||
targetElementType = builder.getIndexedType(targetElementType, dims);
|
||||
// 先推断 LValue 的类型
|
||||
// 如果 LValue 是指向数组的指针,则需要根据 indices 获取正确的类型
|
||||
// 如果 LValue 是标量,则直接使用其类型
|
||||
// 注意:LValue 的类型可能是指向数组的指针 (e.g., int(*)[3]) 或者指向标量的指针 (e.g., int*) 也能推断
|
||||
Type* LType = builder.getIndexedType(variable->getType(), indices);
|
||||
Type* RType = RValue->getType();
|
||||
|
||||
// 左值右值类型不同处理:根据最终元素类型进行转换
|
||||
if (targetElementType != value->getType()) {
|
||||
ConstantValue * constValue = dynamic_cast<ConstantValue *>(value);
|
||||
if (LType != RType) {
|
||||
ConstantValue * constValue = dynamic_cast<ConstantValue *>(RValue);
|
||||
if (constValue != nullptr) {
|
||||
if (targetElementType == Type::getFloatType()) {
|
||||
value = ConstantFloating::get(static_cast<float>(constValue->getFloat()));
|
||||
if (LType == Type::getFloatType()) {
|
||||
RValue = ConstantFloating::get(static_cast<float>(constValue->getFloat()));
|
||||
} else { // 假设如果不是浮点型,就是整型
|
||||
value = ConstantInteger::get(static_cast<int>(constValue->getInt()));
|
||||
RValue = ConstantInteger::get(static_cast<int>(constValue->getInt()));
|
||||
}
|
||||
} else {
|
||||
if (targetElementType == Type::getFloatType()) {
|
||||
value = builder.createIToFInst(value);
|
||||
if (LType == Type::getFloatType()) {
|
||||
RValue = builder.createIToFInst(RValue);
|
||||
} else { // 假设如果不是浮点型,就是整型
|
||||
value = builder.createFtoIInst(value);
|
||||
RValue = builder.createFtoIInst(RValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算目标地址:如果 dims 为空,就是变量本身地址;否则通过 GEP 计算
|
||||
Value* targetAddress = variable;
|
||||
if (!dims.empty()) {
|
||||
targetAddress = getGEPAddressInst(variable, dims);
|
||||
}
|
||||
|
||||
builder.createStoreInst(value, targetAddress);
|
||||
builder.createStoreInst(RValue, LValue);
|
||||
|
||||
return std::any();
|
||||
}
|
||||
@@ -711,7 +746,7 @@ unsigned SysYIRGenerator::countArrayDimensions(Type* type) {
|
||||
|
||||
std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
||||
std::string name = ctx->Ident()->getText();
|
||||
User* variable = module->getVariable(name);
|
||||
Value* variable = module->getVariable(name);
|
||||
|
||||
Value* value = nullptr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user