源码路径
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相关,暂不分析。