我正在使用Clang作为库来生成一些LLVM IR模块。

这是模块的源代码:

inline int getSevenInline() {
  return 7;
}

int getSeven() {
  return getSevenInline();
}

我希望LLVM IR模块包含一个函数getSeven,该函数返回7

这是我的程序生成的LLVM IR:
; ModuleID = './test.cpp'
source_filename = "./test.cpp"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"

; Function Attrs: noinline ssp uwtable
define i32 @_Z8getSevenv() #0 {
entry:
  %call = call i32 @_Z14getSevenInlinev()
  ret i32 %call
}

declare i32 @_Z14getSevenInlinev() #1

attributes #0 = { noinline ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

当我尝试执行模块时,它无法解析getSevenInline的符号。

IR似乎有两种错误:
  • 该函数getSevenInline不应该存在,因为它应该内联
  • 尽管未内联,但getSevenInline没有实现

  • 我应该在clang::CompilerInstance上配置什么,以便正确编译inline函数?

    我只有inline函数有问题;非inline函数正常工作。

    不幸的是,我有太多代码无法发布生成IR的整个程序,但是我希望有人可以指出我在Clang源代码中的配置。

    最佳答案

    C++规范使编译器可以决定何时或何时不内联函数。即使您将函数显式声明为内联函数,就编译器而言,它仍然只是一个建议,如果它决定生成的机器代码过于肿或效率低下,则可以随意忽略该建议。它还很大程度上取决于传递给编译器的优化标志以及许多其他与实现相关的细节,这些细节完全由编译器实现者决定。

    C++ FAQ包含有关该主题的更多详细信息:


    inline关键字的作用是保证您不会因同名函数而遇到多个定义错误。例如,如果您拥有(在myinlines.h中):

    inline int add(int a, int b)
    {
        return a + b;
    }
    

    并且在myinlines.hfile1.cpp中包括file2.cpp时,即使将file1.ofile2.o链接到最终可执行文件中,即使它们都包含int add(int, int)的定义,也不会出现链接器错误。 CPPReference有更多详细信息:

    09-10 06:36
    查看更多