llvm libLLVMCore源码分析 22 - DebugInfoMetadata

本文介绍了LLVM中用于调试信息的元数据类型DebugInfoMetadata,包括DILocation、DIExpression等核心概念及其在IR中的应用实例。此外还详细解释了DIGlobalVariableExpression和DIMacroNode的作用及使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码路径

llvm\include\llvm\IR\Metadata.h

llvm\include\llvm\IR\DebugInfoMetadata.h

DebugInfoMetadata

DebugInfoMetadata是特殊的元数据类型,用于调试:

除了MDTuple,其余都是 DebugInfoMetadata。

DILocation

DILocation表示源代码中的位置。用第1个Operand表示范围,类型为DILocalScope;用第2个Operand表示函数Inline的位置,只在该处位置存在函数inline的时候存在。

class DILocation : public MDNode {
  Metadata *getRawScope() const { return getOperand(0); }
  DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
  Metadata *getRawInlinedAt() const {
    if (getNumOperands() == 2)
      return getOperand(1);
    return nullptr;
  }
  DILocation *getInlinedAt() const {
    return cast_or_null<DILocation>(getRawInlinedAt());
  }
};

IR示例如下:

!0 = !DILocation(line: 2900, column: 42, scope: !1, inlinedAt: !2)

DIExpression

表示DWARF Expression,用Operand从左往右依次存储DWARF Expression的操作数和操作符。被用到llvm debug intrinsic中(如llvm.dbg.declare and llvm.dbg.value)。

当前支持的操作符:

  • DW_OP_deref:解引用expression stack的栈顶。
  • DW_OP_plus :从expression stack中pop两个元素,相加后把结果压栈。
  • DW_OP_minus :从expression stack中pop两个元素,相减后把结果压栈。
  • DW_OP_plus_uconst, 93:表达式加上93
  • DW_OP_LLVM_fragment,16,8 :varible frament在表达式中的offset为16,size为8
  • DW_OP_LLVM_convert, 16, DW_ATE_signed:expression stack栈顶元素转换为16bit,DW_ATE_signed类型。
  • DW_OP_LLVM_tag_offset, tag_offset:offset偏移处的memory tag应用到指针。
  • DW_OP_swap:交换expression stack中的两个元素。
  • DW_OP_xderef:expression stack的栈顶元素作为地址,expression stack的第2个元素作为addrspace。
  • DW_OP_stack_value:标记一个常量。
  • DW_OP_LLVM_entry_value,N:在MIR中使用。
  • DW_OP_LLVM_arg,N:用于引用多个值的intrinsics。
  • DW_OP_breg:表示指定寄存器中的有符号的offset。
  • DW_OP_push_object_address :将对象的地址压栈。
  • DW_OP_over:复制expression stack中的第二个entry。
  • DW_OP_LLVM_implicit_pointer :表达一个解引用的值。

IR示例如下:

IR for "*ptr = 4;"
--------------
call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !20)
!17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
                       type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!20 = !DIExpression(DW_OP_LLVM_implicit_pointer))

IR for "**ptr = 4;"
--------------
call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !21)
!17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
                       type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64)
!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!21 = !DIExpression(DW_OP_LLVM_implicit_pointer,
                    DW_OP_LLVM_implicit_pointer))

DIGlobalVariableExpression 

DIGlobalVariableExpression,表示一对(DIGlobalVariable,DIExpression),用第1个Operand表示DIGlobalVariable,用第2个操作数表示DIExpression。

class DIGlobalVariableExpression : public MDNode {
  Metadata *getRawVariable() const { return getOperand(0); }

  DIGlobalVariable *getVariable() const {
    return cast_or_null<DIGlobalVariable>(getRawVariable());
  }

  Metadata *getRawExpression() const { return getOperand(1); }

  DIExpression *getExpression() const {
    return cast<DIExpression>(getRawExpression());
  }
};

IR示例如下:

@lower = global i32, !dbg !0
@upper = global i32, !dbg !1
!0 = !DIGlobalVariableExpression(
         var: !2,
         expr: !DIExpression(DW_OP_LLVM_fragment, 0, 32)
         )
!1 = !DIGlobalVariableExpression(
         var: !2,
         expr: !DIExpression(DW_OP_LLVM_fragment, 32, 32)
         )
!2 = !DIGlobalVariable(name: "split64", linkageName: "split64", scope: !3,
                       file: !4, line: 8, type: !5, declaration: !6)

 DIMacroNode

表示DWARF MACRO信息(DW_MACINFO_*),有2个子类:DIMacro,DIMacroFile。

DlMacro

表示宏的定义和去定义,用第1个Operand存储名字,第2个Operand存储值:

class DIMacro : public DIMacroNode {
  StringRef getName() const { return getStringOperand(0); }
  StringRef getValue() const { return getStringOperand(1); }

  MDString *getRawName() const { return getOperandAs<MDString>(0); }
  MDString *getRawValue() const { return getOperandAs<MDString>(1); }
};

IR示例如下:

!2 = !DIMacro(macinfo: DW_MACINFO_define, line: 7, name: "foo(x)",
              value: "((x) + 1)")
!3 = !DIMacro(macinfo: DW_MACINFO_undef, line: 30, name: "foo")

DIMacroFile

表示include方式引入的宏,用第1个Operand存储include的DIFile,第2个保存包含的DIMacroNodeArray(一组DlMacro和DIMacroFile):

class DIMacroFile : public DIMacroNode {
  DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }

  DIMacroNodeArray getElements() const {
    return cast_or_null<MDTuple>(getRawElements());
  }

  Metadata *getRawFile() const { return getOperand(0); }
  Metadata *getRawElements() const { return getOperand(1); }
};

IR示例如下:

!2 = !DIMacroFile(macinfo: DW_MACINFO_start_file, line: 7, file: !2,
                  nodes: !3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值