llvm libLLVMCore源码分析 23 - DINode

源码路径

llvm\include\llvm\IR\Metadata.h

llvm\include\llvm\IR\DebugInfoMetadata.h

DINode

表示DWARF标签信息(DW_TAG_*),DINode继承树如下:

GenericDINode

泛化的类DWARF元数据类型,第一个Operand是一个MDString,其余的Operand是对其他Metadata的指针。

IR示例如下:

!0 = !{}
!1 = !GenericDINode(tag: 3, header: "some\00header", operands: {!0, !3, !4})
!2 = !GenericDINode(tag: 3, header: "some\00header", operands: {!{}, !3, !4})
!3 = !GenericDINode(tag: 3)
!4 = !GenericDINode(tag: 3, header: "")

DISubrange

DISubrange用作DICompositeType(DW_TAG_array_type)的成员,表示数组的上下界。用int64_t表示LowerBound,用第一个Operand表示Count,Operand是ConstantInt或DIVariable类型:

class DISubrange : public DINode {    
    int64_t LowerBound;
    Metadata *getRawCountNode() const {
       return getOperand(0).get();
    }
};

IR示例如下:

!0 = !DISubrange(count: 5, lowerBound: 0) ; Count为ConstantInt类型,表示[0,5)
!1 = !DISubrange(count: 5, lowerBound: 1) ; Count为ConstantInt类型,表示[1,6)
!2 = !DISubrange(count: -1) ; Count为ConstantInt类型,表示[]

!6 = !DIFile(filename: "vla.c", directory: "/path/to/file")
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !6)
!8 = distinct !DISubprogram(name: "foo", scope: !7, file: !6, line: 5)

; Count为DIVariable类型,表示[0,0+!10)
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!10 = !DILocalVariable(name: "count", scope: !8, file: !6, line: 42, type: !9)
!11 = !DISubrange(count: !10, lowerBound: 0)

; Count为DIVariable类型,表示[0,0+!12)
!12 = !DIGlobalVariable(name: "count", scope: !8, file: !6, line: 22, type: !9)
!13 = !DISubrange(count: !12, lowerBound: 0)

DIEnumerator

DISubrange用作DICompositeType(DW_TAG_enumeration_type)的成员,表示枚举的值。用int64_t表示Value,用第一个Operand表示名字,Operand是MDString类型:

class DIEnumerator : public DINode {
  StringRef getName() const { return getStringOperand(0); }
  MDString *getRawName() const { return getOperandAs<MDString>(0); }
};

IR示例如下:

!0 = !DIEnumerator(name: "SixKind", value: 7)
!1 = !DIEnumerator(name: "SevenKind", value: 7)
!2 = !DIEnumerator(name: "NegEightKind", value: -8)

DIScope

是所有范围类上下文的基类,继承树如下:

DIFile

表示文件,用第1个Operand表示文件名,用第2个Operand表示目录:

class DIFile : public DIScope {
  MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
  MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
  Optional<MDString *> getRawSource() const { return Source; }
};

IR示例如下:

!0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir",
             checksumkind: CSK_MD5,
             checksum: "000102030405060708090a0b0c0d0e0f")

DIType

DIBasicType

表示primitive types:

  • int 
  • float
  • bool
  • char  
  • address

IR示例如下:

!0 = !DIBasicType(name: "unsigned char", size: 8, align: 8,
                  encoding: DW_ATE_unsigned_char)
!1 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")

DIDerivedType

表示Derived Types:

  • qualified type
  • pointer
  • reference
  • friend
  • typedef
  • class member

源代码:

struct layout1 {
  char a;
  int b : 1;
};

IR示例如下:

!27 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "layout1", file: !1, line: 3, size: 32, flags: DIFlagTypePassByValue, elements: !28, identifier: "_ZTS7layout1")
!28 = !{!29, !31}
!29 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !27, file: !1, line: 4, baseType: !30, size: 8)
!30 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
!31 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !27, file: !1, line: 5, baseType: !11, size: 1, offset: 8, flags: DIFlagBitField, extraData: i64 8)

DICompositeType

表示组合类型,比如struct/class等,IR示例同DIDerivedType。

DISubroutineType

表示DISubprogram的返回值、参数类型。

源代码:


int foo(int  a, int  b) {
	return a + b;
}

IR示例如下:

!9 = !DISubroutineType(types: !10)
!10 = !{!11, !11, !11}
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)

DICompileUnit

表示编译单元,Operands存储内容如下:

  • Operand0:DIFile
  • Operand1:MDString表示Producer
  • Operand2:MDString表示Flags
  • Operand3:MDString表示DebugFilename
  • Operand4:DICompositeTypeArray表示EnumTypes
  • Operand5:DIScopeArray表示RetainedTypes
  • Operand6:DIGlobalVariableExpressionArray表示GlobalVariables和对应的DWARF Expression
  • Operand7:DIImportedEntityArray表示ImportedEntities
  • Operand8:DIMacroNodeArray表示Macros

IR示例如下:

!0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang",
                    isOptimized: true, flags: "-O2", runtimeVersion: 2,
                    splitDebugFilename: "abc.debug", emissionKind: FullDebug,
                    enums: !2, retainedTypes: !3, globals: !4, imports: !5,
                    macros: !6, dwoId: 0x0abcd)

DILocalScope

表示Local Scope,继承树如下:

DISubprogram

DISubprogram表示源代码中的Function,distinct的DISubprogram可以和函数定义,unique的DISubprogram可以和函数声明绑定。Operands存储内容如下:

  • Operand0:DIFile
  • Operand1:DIScope表示所属的Scope(DIFile/DINamespace等)
  • Operand2:MDString表示Function Name
  • Operand3:MDString表示Function LinkageName
  • Operand4:DISubroutineType表示函数的返回值和参数类型
  • Operand5:DICompileUnit表示所属的编译单元
  • Operand6:DISubprogram表示DISubprogram的声明
  • Operand7:DINodeArray表示需要retain的Variables和Label(由于优化的原因在IR中不存在)。
  • Operand8(可选):DIType表示Containing Type。
  • Operand9(可选):DIType表示Template Parameter。
  • Operand10(可选):DITypeArray表示抛出异常的Type。

 IR示例如下:

define dso_local i32 @_Z3fooii(i32 %a, i32 %b) #0 !dbg !8 {
entry:
  %a.addr = alloca i32, align 4
  %b.addr = alloca i32, align 4
  store i32 %a, i32* %a.addr, align 4
  call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !12, metadata !DIExpression()), !dbg !13
  store i32 %b, i32* %b.addr, align 4
  call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !14, metadata !DIExpression()), !dbg !15
  %0 = load i32, i32* %a.addr, align 4, !dbg !16
  %1 = load i32, i32* %b.addr, align 4, !dbg !17
  %add = add nsw i32 %0, %1, !dbg !18
  ret i32 %add, !dbg !19
}

; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1

attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone speculatable willreturn }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5, !6}
!llvm.ident = !{!7}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 10.0.1 (git@code-sh.rnd.huawei.com:llvm-wx/llvm-project.git dfc7eb43ab34e2500b0877414126950a12636de8)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "debug.cpp", directory: "D:\\2022\\llvm")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 2}
!6 = !{i32 7, !"PIC Level", i32 2}
!7 = !{!"clang version 10.0.1 (git@code-sh.rnd.huawei.com:llvm-wx/llvm-project.git dfc7eb43ab34e2500b0877414126950a12636de8)"}
!8 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooii", scope: !1, file: !1, line: 3, type: !9, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!9 = !DISubroutineType(types: !10)
!10 = !{!11, !11, !11}
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!12 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 3, type: !11)
!13 = !DILocation(line: 3, column: 13, scope: !8)
!14 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 3, type: !11)
!15 = !DILocation(line: 3, column: 20, scope: !8)
!16 = !DILocation(line: 4, column: 9, scope: !8)
!17 = !DILocation(line: 4, column: 13, scope: !8)
!18 = !DILocation(line: 4, column: 11, scope: !8)
!19 = !DILocation(line: 4, column: 2, scope: !8)

DILexicalBlock

表示DISubprogram中的嵌套的语句块(如C++中的{})。

Operands存储内容如下:

  • Operand0:DIFile
  • Operand1:DIScope表示DILexicalBlock所属的Scope(DISubprogram)。

IR示例如下:

!0 = distinct !DILexicalBlock(scope: !1, file: !2, line: 7, column: 35)

DILexicalBlockFile

表示不同控制流下的DILexicalBlock。

Operands存储内容如下:

  • Operand0:DIFile
  • Operand1:DIScope表示DILexicalBlock所属的Scope(DILexicalBlock)。

IR示例如下:

!0 = !DILexicalBlock(scope: !3, file: !4, line: 7, column: 35)
!1 = !DILexicalBlockFile(scope: !0, file: !4, discriminator: 0)
!2 = !DILexicalBlockFile(scope: !0, file: !4, discriminator: 1)

DINamespace

表示Namspace。

Operands存储内容如下:

  • Operand0:DIFile
  • Operand1:DIScope表示DINamespace所属的Scope。

IR示例如下:

!0 = !DINamespace(name: "myawesomeproject", scope: !1, file: !2, line: 7)

DIModule

Object C相关。

DICommonBlock

Fortran相关。

DITemplateParameter

表示Template parameter。

Operands存储内容如下:

  • Operand0:MDString表示Name
  • Operand1:DIType表示类型。

IR示例如下:

!21 = !DITemplateTypeParameter(name: "T", type: !11)

!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)

DIVariable

表示变量,有2个子类:DIGlobalVariable、DILocalVariable。

DIGlobalVariable

表示全局变量。

Operands存储内容如下:

  • Operand0:DIScope表示所在的Scope。
  • Operand1:MDString表示Name。
  • Operand2:DIFile表示所在的File。
  • Operand3:DIType表示Type。
  • Operand4:MDString表示Display Name。
  • Operand5:MDString表示Linkage Name。
  • Operand6:DIDerivedType表示静态成员类型。

  • Operand7:MDTuple表示template parameters。

IR示例如下:

!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 3, type: !6, isLocal: false, isDefinition: true)

DILocalVariable

表示局部变量。

Operands存储内容如下:

  • Operand0:DIScope表示所在的Scope。
  • Operand1:MDString表示Name。
  • Operand2:DIFile表示所在的File。
  • Operand3:DIType表示Type。

IR示例如下:

!25 = !DILocalVariable(name: "a", arg: 1, scope: !20, file: !3, line: 11, type: !6)

DILabel

表示Label。

Operands存储内容如下:

  • Operand0:DILabel表示所在的Scope,必须是DILocalScope。
  • Operand1:MDString表示Name。
  • Operand2:DIFile表示所在的File。

IR示例如下:

!2 = !DILabel(scope: !0, name: "foo", file: !1, line: 7)

DIImportedEntity

对应C++的using关键字。

Operands存储内容如下:

  • Operand0:DIImportedEntity表示所在的Scope。
  • Operand1:DINode表示import的Entity。
  • Operand2:MDString表示所在的Name。
  • Operand3:DIType表示Type。

IR示例如下:

!7 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !8, file: !3, line: 2)
!8 = !DINamespace(name: "std", scope: null)

DIObjCProperty

Object C相关,暂不分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值