LLVM 自带的 ptr 是完全不带存储类型的啊,我搁哪找半天获取元素的 API,搞半天还得是 Tuple 传递显式 Type
// BUG 这里不考虑对函数返回的对象的引用
std::any GenVisitor::visitBlendExpr(RiddleParser::BlendExprContext *ctx) {
// todo 这里暂时没法使用对象的函数
const auto [parent, type] = std::any_cast<std::tuple<llvm::Value *, llvm::Type *>>(visit(ctx->parent));
const auto childName = ctx->child->getText();
ClassNode theClass;
if(const auto Alloca = llvm::dyn_cast<llvm::AllocaInst>(parent)) {
theClass = classManager.getClass(Alloca->getAllocatedType()->getStructName().str());
} else {
theClass = classManager.getClass(type->getStructName().str());
}
if(const auto FuncExpr = dynamic_cast<RiddleParser::FuncExprContext *>(ctx->child)) {
const auto func = theClass.get().funcs.at(childName);
const auto args = any_cast<std::vector<llvm::Value *>>(visit(FuncExpr->args));
llvm::Value *result = Builder.CreateCall(func, args);
return std::tuple{result, result->getType()};
} else {
const auto it = theClass.get().names.find(childName);
if(it == theClass.get().names.end()) {
throw std::logic_error("没有这个成员");
}
llvm::Value *result = Builder.CreateStructGEP(theClass.get().types, parent, it->second);
return std::tuple{result, theClass.get().types->getElementType(it->second)};
}
}