2016-11-24 46 views
0

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

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

function f(int i, float r) returns int { return i; } 
function f(float r, float r2) returns int {return i; } 

我认为LLVM可能不同,但我得到

error: invalid redefinition of function

我生成的代码是:

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()来区分所有这些功能?

+0

我m为动态类型语言做同样的事情,我已经开始将函数签名生成为'@ modulename_functionname_xyz',其中'xy'对arity进行编码。在你的情况下,你可以编码的类型。例如。 @ foo.f_if和@ foo.f_ff。 –

+0

@FrankC。我想后来改变这个事情,但现在我会通过反制来区分它,因为我不是唯一一个从事这件事的人。 –

回答

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

实现函数重载的典型方法是使用name mangling,以某种方式将函数的类型签名编码到其名称中,以便在重载情况下它是唯一的。

+0

你说得对,我忘了运行时库也可能有同名的函数。 –

1

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

我的表是通过地图与函数名作为关键字定义,和值函数DEF的列表:

Map<String,ArrayList<functionSymbol>> = new HashMap<>();

,然后构造看起来像:

static int counter = 0; 
public FunctionSymbol(String functionName, Type retType, List<Variable> paramList){ 
    this.functionName = functionName+counter; 
    this.paramList = paramList; 
    this.retType = retType; 
    counter++; 
}