【问题标题】:What are "retainedNodes" in LLVMs debug metadata?LLVM 调试元数据中的“retainedNodes”是什么?
【发布时间】:2020-03-25 09:47:54
【问题描述】:

使用 LLVM 8.0.1 库,我尝试使用以下代码为函数创建调试信息:

DIFile *Unit = DebugBuilder->createFile(CompileUnit->getFilename(), CompileUnit->getDirectory());
DIScope *FContext(Unit);

DISubprogram *SP = DebugBuilder->createFunction(
    FContext, def->Name, def->Name, Unit, LineNo,
    CreateFunctionType(ft, CompileUnit->getFile()), 0);

func->setSubprogram(SP);

然而,这会导致 IR 如下所示:

define i32 @main(i32 %y) !dbg !3 {
entry:
  ret i32 2
}
    ; ...
!3 = !DISubprogram(name: "main", linkageName: "main", scope: !2, file: !2, type: !4, spFlags: 0, retainedNodes: !7)
    ; ...
!7 = <temporary!> !{}

在调用 DebugBuilder-&gt;finalize() 时,会抛出 Assertion failed: !N-&gt;isTemporary() &amp;&amp; "Expected all forward declarations to be resolved"

我在官方参考资料和其他教程中都没有找到对retainedNodes 字段的描述,并且网络搜索只会导致 LLVM 源代码中未注释的部分。这个领域的意义或目的是什么?临时节点是如何在那里创建的?

【问题讨论】:

    标签: visual-c++ compiler-construction llvm debug-information


    【解决方案1】:

    我发现在生成 DebugBuilder 之前添加解决了这个问题,

    TheModule->addModuleFlag(llvm::Module::Warning, "CodeView", 1);
    

    ...正如官方文档中明显nowhere所解释的那样。

    【讨论】:

      【解决方案2】:

      我在使用 LLVM C API 时遇到了同样的问题(使用 inkwell-rs 作为包装器)。我通过使用IsDefinition = trueIsLocalToUnit = true 调用LLVMDIBuilderCreateFunction 解决了这个问题。这将保留 retainedNodes 元数据节点,但其值为空元数据 (!{}) 而不是临时的。

      【讨论】:

        【解决方案3】:

        我通过使用 finalizeSubprogram 显式结束子程序解决了类似的问题。

        DebugBuilder->finalizeSubprogram(SP);
        

        这似乎解决了临时问题,但在编译生成的 IR 时我仍然收到一些警告。

        如果通过将DISubprogram::SPFlagDefinition 标志添加到DebugBuilder-&gt;createFunction 调用来定义函数,retainedNodes 将被设置为空节点而不是临时节点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-07-31
          • 2019-09-10
          • 1970-01-01
          • 1970-01-01
          • 2011-01-22
          • 2012-10-07
          • 2012-02-10
          相关资源
          最近更新 更多