#include "Entity/Scope.h"
#include "CodeGen/IRGenerator.h"
void IRGenerator::visit(const SharedPtr &varDecl) {
ASTVisitor::visit(varDecl);
LLVMType *type = getType(varDecl->type);
LLVMValue *varInitCode = varDecl->initVal->code;
bool isLiteralInit = bool(dynPtrCast(varDecl->initVal));
bool declBoolean = varDecl->type->isBoolean();
bool declFloat = varDecl->type->isFloat();
bool initFloat = varDecl->initVal->type->isFloat();
bool declString = varDecl->type->isString();
bool declArray = varDecl->type->isArray();
if (declFloat && !initFloat) {
varInitCode = integer2float(varInitCode);
} else if (!declFloat && initFloat) {
varInitCode = float2integer(varInitCode);
}
// åºåå
¨å±åéåå±é¨åé
if (varDecl->scope->isTopLevel()) {
llvm::Constant *initializer;
if (declString || declArray) {
initializer = llvm::ConstantPointerNull::getNullValue(type);
} else if (isLiteralInit) {
if (declFloat) {
initializer = llvm::cast<:constantfp>(varInitCode);
} else {
initializer = llvm::cast(varInitCode);
}
} else {
if (declFloat) {
// åå§å¼ä¸ºæµ®ç¹è¡¨è¾¾å¼
initializer = llvm::ConstantFP::get(type, 0.0);
} else {
// åå§å¼ä¸ºå¸å°åæ´æ°è¡¨è¾¾å¼
initializer = llvm::ConstantInt::get(type, 0);
}
}
auto *gVar = new LLVMGlobalVariable(
*llvmModule,
type,
false,
LLVMGlobalValue::ExternalLinkage,
initializer,
varDecl->name
);
uint64_t alignment = 8;
if (declBoolean) {
alignment = 1;
}
gVar->setAlignment(llvm::MaybeAlign(alignment));
// å¨main彿°ä¸storeåç¬¦ä¸²åæ°ç»çæé弿è
éåé¢éç表达å¼å¼
// å
¨å±åéåå§å¼ä¸ºåé¢éæ¶ä¸éè¦å¨store varInitCode
if (declString || declArray || !isLiteralInit) {
llvmIRBuilder.CreateStore(varInitCode, gVar);
}
varDecl->code = gVar;
} else {
LLVMValue *alloca = llvmIRBuilder.CreateAlloca(type);
llvmIRBuilder.CreateStore(varInitCode, alloca);
varDecl->code = alloca;
}
}
// delete
void IRGenerator::visit(const SharedPtr ¶mVarDecl) {
ASTVisitor::visit(paramVarDecl);
}
void IRGenerator::visit(const SharedPtr &funcDecl) {
Vector argsType;
for (const auto ¶m: funcDecl->params) {
argsType.push_back(getType(param->type));
}
LLVMType *returnType = getType(funcDecl->returnType);
LLVMFunctionType *funcType = LLVMFunctionType::get(returnType, argsType, false);
LLVMFunction *func = LLVMFunction::Create(funcType, LLVMFunction::ExternalLinkage, funcDecl->name, llvmModule.get());
curFn = func;
LLVMBasicBlock *entryBlock = createBasicBlock("entry", func);
llvmIRBuilder.SetInsertPoint(entryBlock);
for (size_t i = 0; i < func->arg_size(); ++i) {
auto arg = func->getArg(i);
arg->setName(funcDecl->params[i]->name);
LLVMValue *paramAlloca = llvmIRBuilder.CreateAlloca(getType(funcDecl->params[i]->type));
llvmIRBuilder.CreateStore(arg, paramAlloca);
funcDecl->params[i]->code = paramAlloca;
}
funcDecl->body->accept(shared_from_this());
// 妿è¿åç±»å为voidè䏿²¡ææ¾å¼returnçè¯åæ·»å retæä»¤
if (funcDecl->returnType == nullptr) {
LLVMBasicBlock *curBB = llvmIRBuilder.GetInsertBlock();
if (!curBB->getTerminator()) {
llvmIRBuilder.CreateRetVoid();
}
}
llvm::verifyFunction(*func);
curFn = mainFn;
}