【发布时间】:2019-04-17 21:43:34
【问题描述】:
我正在尝试为支持嵌套函数的语言编写编译器,例如:
func a()
int x;
func b()
int y;
{
// code of func b - both x and y are visible here
}
{
// code of func a - only x is visible here
}
我在 C++ 中使用 LLVM API 来编译代码。我的问题是我不知道如何使变量 x 在函数 b 中可见,因为据我所知 llvm 不支持嵌套函数。我现在声明变量的方式是这个函数:
static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName, Type *T) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin());
return TmpB.CreateAlloca(T, 0, VarName.c_str());
}
如llvm教程https://llvm.org/docs/tutorial/LangImpl07.html#adjusting-existing-variables-for-mutation所示。
当使用此声明并尝试在嵌套函数中使用外部变量时,会弹出此错误:指令不支配所有使用!。
有没有办法解决这个问题?
【问题讨论】:
-
c++ 除了 lambda 函数定义外,不支持嵌套函数定义。目前还不清楚你在追求什么。
-
这不是受支持的 C++ 编程实践。如果要访问父函数中的变量,请传递对它的引用。
-
我正在尝试将示例中的代码(带有函数 a 和 b)编译为 llvm 代码(不确定这是否是所谓的),以使用
llc编译。但是因为 llvm 是一种类似 c 的语言并且不支持嵌套函数,所以我需要另一种方法来使变量x在函数b中可见和可访问。全局变量是一种方法,但我认为使用它们并不可行。 -
@JohnFikioris 所以这就是实际的编译器所做的:他们将这样的嵌套函数转换为具有构造函数和方法的类(作为实际的函数体)。构造函数获取外部变量的引用(或值,依赖)并将其存储在对象中。然后将代码转化为“创建对象”和“调用方法”指令。这就是你需要实现的。
-
@freakish 你有什么建议吗?