LLVM 调试元数据中的 "retainedNodes" 是什么?
What are "retainedNodes" in LLVMs debug metadata?
使用 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->finalize()
时抛出 Assertion failed: !N->isTemporary() && "Expected all forward declarations to be resolved"
我没有在官方参考资料和其他教程中找到对 retainedNodes
字段的描述,网络搜索只能找到 LLVM 源代码中未注释的部分。该字段的含义或用途是什么?那里是如何创建临时节点的?
我发现在生成 DebugBuilder
、
之前添加解决了这个问题
TheModule->addModuleFlag(llvm::Module::Warning, "CodeView", 1);
...正如官方文档中显然无处所解释的那样。
我在 LLVM C API 中遇到了同样的问题(使用 inkwell-rs
作为包装器)。我通过使用 IsDefinition = true
和 IsLocalToUnit = true
调用 LLVMDIBuilderCreateFunction
解决了这个问题。这保留了 retainedNodes
元数据节点,但它的值是空元数据 (!{}
) 而不是临时的。
我通过使用 finalizeSubprogram 显式完成子程序解决了类似的问题。
DebugBuilder->finalizeSubprogram(SP);
这似乎解决了临时问题,但在编译生成的 IR 时,我仍然收到一些警告。
如果您通过将 DISubprogram::SPFlagDefinition
标志添加到 DebugBuilder->createFunction
调用来定义函数,则 retainedNodes 将设置为空节点而不是临时节点。
使用 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->finalize()
时抛出 Assertion failed: !N->isTemporary() && "Expected all forward declarations to be resolved"
我没有在官方参考资料和其他教程中找到对 retainedNodes
字段的描述,网络搜索只能找到 LLVM 源代码中未注释的部分。该字段的含义或用途是什么?那里是如何创建临时节点的?
我发现在生成 DebugBuilder
、
TheModule->addModuleFlag(llvm::Module::Warning, "CodeView", 1);
...正如官方文档中显然无处所解释的那样。
我在 LLVM C API 中遇到了同样的问题(使用 inkwell-rs
作为包装器)。我通过使用 IsDefinition = true
和 IsLocalToUnit = true
调用 LLVMDIBuilderCreateFunction
解决了这个问题。这保留了 retainedNodes
元数据节点,但它的值是空元数据 (!{}
) 而不是临时的。
我通过使用 finalizeSubprogram 显式完成子程序解决了类似的问题。
DebugBuilder->finalizeSubprogram(SP);
这似乎解决了临时问题,但在编译生成的 IR 时,我仍然收到一些警告。
如果您通过将 DISubprogram::SPFlagDefinition
标志添加到 DebugBuilder->createFunction
调用来定义函数,则 retainedNodes 将设置为空节点而不是临时节点。