[IR gen] introduced IR builder into LLVMIRGenerator

This commit is contained in:
Lixuanwang
2025-06-09 00:47:47 +08:00
parent df209f976e
commit 5e84961dcf
2 changed files with 57 additions and 7 deletions

View File

@ -5,8 +5,18 @@
// TODO对while、continue、break的测试
#include "LLVMIRGenerator.h"
#include <iomanip>
using namespace std;
namespace sysy {
std::string LLVMIRGenerator::generateIR(SysYParser::CompUnitContext* unit) {
// 初始化自定义IR数据结构
irModule = std::make_unique<sysy::Module>();
irBuilder = sysy::IRBuilder(); // 初始化IR构建器
tempCounter = 0;
symbolTable.clear();
tmpTable.clear();
globalVars.clear();
inFunction = false;
visitCompUnit(unit);
return irStream.str();
}
@ -25,7 +35,31 @@ std::string LLVMIRGenerator::getLLVMType(const std::string& type) {
return "i32";
}
sysy::Type* LLVMIRGenerator::getSysYType(const std::string& typeStr) {
if (typeStr == "int") return sysy::Type::getIntType();
if (typeStr == "float") return sysy::Type::getFloatType();
if (typeStr == "void") return sysy::Type::getVoidType();
// 处理指针类型等
return sysy::Type::getIntType();
}
std::any LLVMIRGenerator::visitCompUnit(SysYParser::CompUnitContext* ctx) {
auto type_i32 = Type::getIntType();
auto type_f32 = Type::getFloatType();
auto type_void = Type::getVoidType();
auto type_i32p = Type::getPointerType(type_i32);
auto type_f32p = Type::getPointerType(type_f32);
// 创建运行时库函数
irModule->createFunction("getint", sysy::FunctionType::get(type_i32, {}));
irModule->createFunction("getch", sysy::FunctionType::get(type_i32, {}));
irModule->createFunction("getfloat", sysy::FunctionType::get(type_f32, {}));
//TODO: 添加更多运行时库函数
irStream << "declare i32 @getint()\n";
irStream << "declare i32 @getch()\n";
irStream << "declare float @getfloat()\n";
//TODO: 添加更多运行时库函数的文本IR
for (auto decl : ctx->decl()) {
decl->accept(this);
}
@ -51,8 +85,10 @@ std::any LLVMIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) {
if (varDef->ASSIGN()) {
value = std::any_cast<std::string>(varDef->initVal()->accept(this));
} else {
std::cout << "[WR-Release-01]Warning: Global variable '" << varName
<< "' is declared without initialization, defaulting to 0.\n";
}
irStream << "@" << varName << " = dso_local global " << llvmType << " " << value << ", align 4\n";
globalVars.push_back(varName); // 记录全局变量
} else {
@ -76,9 +112,9 @@ std::any LLVMIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
try {
value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
} catch (...) {
throw std::runtime_error("Const value must be initialized upon definition.");
throw std::runtime_error("[ERR-Release-01]Const value must be initialized upon definition.");
}
// 如果是 float 类型,转换为十六进制表示
if (llvmType == "float") {
try {
double floatValue = std::stod(value);
@ -87,7 +123,7 @@ std::any LLVMIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
ss << "0x" << std::hex << std::uppercase << hexValue;
value = ss.str();
} catch (...) {
throw std::runtime_error("Invalid float literal: " + value);
throw std::runtime_error("[ERR-Release-02]Invalid float literal: " + value);
}
}
@ -632,4 +668,5 @@ std::any LLVMIRGenerator::visitLOrExp(SysYParser::LOrExpContext* ctx) {
left = temp;
}
return left;
}
}