LLVM错误:函数的重新定义无效

LLVM错误:函数的重新定义无效,llvm,llvm-clang,llvm-ir,Llvm,Llvm Clang,Llvm Ir,我正在为一种伪代码语言编写一个LLVM IR生成器。这种语言应该允许重新定义函数 这里有一个例子,我有两个函数都命名为“f”,但它们有不同的参数 function f(int i, float r) returns int { return i; } function f(float r, float r2) returns int {return i; } 我以为LLVM可以区分这一点,但我明白了 错误:函数的重新定义无效 我生成的代码是: define i32 @f(i32 %i, fl

我正在为一种伪代码语言编写一个LLVM IR生成器。这种语言应该允许重新定义函数

这里有一个例子,我有两个函数都命名为“f”,但它们有不同的参数

function f(int i, float r) returns int { return i; }
function f(float r, float r2) returns int {return i; } 
我以为LLVM可以区分这一点,但我明白了

错误:函数的重新定义无效

我生成的代码是:

define i32 @f(i32 %i, float %r) {
    %var.i.0 = alloca i32
    store i32 %i, i32* %var.i.0
    %var.r.1 = alloca float
    store float %r, float* %var.r.1
    %int.2 = load i32* %var.i.0
    ret i32 %int.2
    ; -- 0 :: i32
    %int.3 = add i32 0, 0

    ret i32 %int.3
}

define i32 @f(float %r, float %r2) {
    %var.r.2 = alloca float
    store float %r, float* %var.r.2
    %var.r2.3 = alloca float
    store float %r2, float* %var.r2.3
    %var.i.4 = alloca i32
    %float.3 = load float* %var.r.2
    %int.7 = fptosi float %float.3 to i32
    store i32 %int.7, i32* %var.i.4
    %int.8 = load i32* %var.i.4
    ret i32 %int.8
    ; -- 0 :: i32
    %int.9 = add i32 0, 0

    ret i32 %int.9
}

所以,我认为LLVM不允许函数重载?那么,我生成一个顺序计数器,并通过将此顺序计数器添加为后缀来区分所有这些函数是否是一个好主意,即
define i32@f.1()
define i32@f.2()

您认为LLVM IR没有函数重载是正确的

根据语言中代码的组织方式,使用顺序计数器可能不是一个好主意。如果您只是分配递增整数,那么在不同文件的编译过程中,这些整数可能不是确定性的。例如,在C++中,你可以想象一些类似于

的东西。
// library.cpp
int f(int i, float r) { ... }
int f(float r, float r2) { ... }

// user.cpp
extern int f(float r, float r2);
int foo() { return f(1.0, 2.0); }
编译
user.cpp
时,编译器无法知道被引用的
f
实际上将被命名为
f.2


实现函数重载的典型方法是使用,以某种方式将函数的类型签名编码为其名称,以便在出现重载时它是唯一的。

我的生成器是用java编写的,因此每次解析函数定义时,如果作用域表中已经存在函数名,我将增加相同函数名的计数器

My table由Map定义,其中函数名作为键,函数定义列表作为值:

Map=newhashmap()

然后构造函数将如下所示:

static int counter = 0;
public FunctionSymbol(String functionName, Type retType,  List<Variable> paramList){
     this.functionName = functionName+counter;
     this.paramList = paramList;
     this.retType = retType;
     counter++;
}
静态整数计数器=0;
公共函数符号(字符串函数名、类型retType、列表参数列表){
this.functionName=functionName+计数器;
this.paramList=paramList;
this.retType=retType;
计数器++;
}

你说得对,我忘了运行时库也可以有相同名称的函数。我对动态类型语言也这么做,并且我已经开始生成函数签名,作为
@modulename\u functionname\u xyz
其中
xy
对算术进行编码。在您的情况下,您可以对类型进行编码。例如@foo.f_if和@foo.f_ff.@FrankC。我想以后再改变这件事,但现在我会通过计数器来区分它,因为我不是唯一一个做这件事的人。