我刚刚开始学习LLVM C ++ API,并且对如何进行类型检查感到有些困惑。我的讲师提供了一个有关将变量存储在堆栈存储器中的示例,如下所示:
llvm::AllocaInst *Alloca;
Alloca = llvm::Builder.CreateAlloca(llvm::IntegerType::get(getGlobalContext(), 32), nullptr, "variable_name");
我理解这一点,但是在下一部分中,它将讨论在将值分配给变量之前进行类型检查。 To assign a value in a Decaf statement of the type lvalue = rvalue you should get the location of lvalue from the symbol table. You can check the type of rvalue using the following API call:
const llvm::PointerType *ptrTy = rvalue->getType()->getPointerTo();
ptrTy == Alloca->getType()
我完全困惑为什么需要进行类型检查。我已经阅读了文档,getPointerTo
返回了PointerType对象。所以我的第一个问题是,Alloca的Type对象是IntegerType,那么为什么要创建PointerType对象?在我看来,这似乎完全不在左领域。
我的第二个问题是,为什么我们再将此PointerType对象与作为IntegerType对象的Alloca Type对象进行比较?是否存在某种==运算符重载?因为我正在搜索文档,所以找不到任何东西。
答案 0 :(得分:2)
您似乎正在关注this tutorial。您的问题缺少一些有价值的内容,我在下面复制了这些内容:
例如,以下代码使用LLVM API创建alloca指令以在堆栈上存储整数(LLVM类型为i32)。该存储空间用于存储值并从堆栈上的存储位置加载值。
llvm::AllocaInst *Alloca; // unlike CreateEntryBlockAlloca the following will // create the alloca instr at the current insertion point // rather than at the start of the block Alloca = llvm::Builder.CreateAlloca(llvm::IntegerType::get(getGlobalContext(), 32), nullptr, "variable_name");
然后应将此指针存储到符号表中,以用于 标识符“ NAME”。您可以使用以下方式访问指向TYPE类型的指针 要为该位置分配值时,
Alloca->getType()
。
因此Alloca->getType()
为您提供了一个PointerType对象,该对象表示“指向i32
的指针”,尤其是指向堆栈中为i32
分配的位置的指针。但是rvalue
是i32
,而不是指向i32
的指针。即使这样,我们仍然可以使用Alloca->getType()
将lvalue
(i32
)的类型与某物(即rvalue
的类型进行比较:
要在类型
lvalue = rvalue
的Decaf语句中分配一个值,您可以 应该从符号表中获取lvalue
的位置。你可以检查一下 使用以下API调用的rvalue
类型:const llvm::PointerType *ptrTy = rvalue->getType()->getPointerTo();
我们首先获得rvalue
的类型。我们无法直接将其与lvalue
的类型进行比较,因为我们只有类型“指向lvalue
的指针”。因此,我们要做的就是将从rvalue
获得的类型对象转换为“ rvalue
的指针类型”,也就是说,我们将其从i32
转换为*i32
换句话说,如果我们需要比较的只是rvalue
类型,我们如何检查i32
是否具有类型*i32
?答案是,我们只是将rvalue
的类型提升为指针类型,即采用其i32
并使其成为指针*i32
。
在这一点上,ptrTy
包含类型“ rvalue
的指针”,而我们也知道Alloca->getType()
给出了类型“ lvalue
的指针” ”。为了将rvalue
分配给lvalue
,我们检查这两种类型是否重合:
并检查左值的Alloca位置的类型是否相同 类型:
ptrTy == Alloca->getType()
上面的表达式是有条件的;如果类型相同则为true,否则为false。假设它是真的,您可以像这样分配值:
llvm::Value *val = Builder.CreateStore(rvalue, Alloca)