Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions llvm/include/llvm-c/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ enum {
};
typedef unsigned LLVMMetadataKind;

/**
* The kind of checksum to emit.
*/
typedef enum { CSK_MD5, CSK_SHA1, CSK_SHA256 } LLVMChecksumKind;

/**
* An LLVM DWARF type encoding.
*/
Expand Down Expand Up @@ -326,6 +331,25 @@ LLVM_C_ABI LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder,
const char *Directory,
size_t DirectoryLen);

/**
* Create a file descriptor to hold debugging information for a file.
* \param Builder The \c DIBuilder.
* \param Filename File name.
* \param FilenameLen The length of the C string passed to \c Filename.
* \param Directory Directory.
* \param DirectoryLen The length of the C string passed to \c Directory.
* \param ChecksumKind The kind of checksum. eg MD5, SHA256
* \param Checksum The checksum.
* \param ChecksumLen The length of the checksum.
* \param Souce The embedded source.
* \param SourceLen The length of the source.
*/
LLVM_C_ABI LLVMMetadataRef LLVMDIBuilderCreateFileWithCheckSum(
LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen,
const char *Directory, size_t DirectoryLen, LLVMChecksumKind ChecksumKind,
const char *Checksum, size_t ChecksumLen, const char *Source,
size_t SourceLen);

/**
* Creates a new descriptor for a module with the specified parent scope.
* \param Builder The \c DIBuilder.
Expand Down
32 changes: 32 additions & 0 deletions llvm/lib/IR/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,38 @@ LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,
StringRef(Directory, DirectoryLen)));
}

static llvm::DIFile::ChecksumKind
map_from_llvmChecksumKind(LLVMChecksumKind CSKind) {
switch (CSKind) {
case LLVMChecksumKind::CSK_MD5:
return llvm::DIFile::CSK_MD5;
case LLVMChecksumKind::CSK_SHA1:
return llvm::DIFile::CSK_SHA1;
case LLVMChecksumKind::CSK_SHA256:
return llvm::DIFile::CSK_SHA256;
}
llvm_unreachable("Unhandled Checksum Kind");
}

LLVMMetadataRef LLVMDIBuilderCreateFileWithCheckSum(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think checksum should be one word (so the S should be lower case in the function name).

LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen,
const char *Directory, size_t DirectoryLen, LLVMChecksumKind ChecksumKind,
const char *Checksum, size_t ChecksumLen, const char *Source,
size_t SourceLen) {
StringRef ChkSum = StringRef(Checksum, ChecksumLen);
std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we drop the optional part here, since it looks like we're expecting to always have a value. I think you can pass the llvm::DIFile::ChecksumInfo<StringRef> directly to the optional<> param?

auto CSK = map_from_llvmChecksumKind(ChecksumKind);
CSInfo.emplace(CSK, ChkSum);
std::optional<StringRef> Src;
if (SourceLen > 0)
Src = StringRef(Source, SourceLen);
else
Src = std::nullopt;
Comment on lines +1123 to +1124
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can drop the else block as I believe a default initialized std::optional is empty

return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen),
StringRef(Directory, DirectoryLen),
CSInfo, Src));
}

LLVMMetadataRef
LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope,
const char *Name, size_t NameLen,
Expand Down
107 changes: 54 additions & 53 deletions llvm/test/Bindings/llvm-c/debug_info_new_format.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,37 @@

; CHECK: ; ModuleID = 'debuginfo.c'
; CHECK-NEXT: source_filename = "debuginfo.c"
; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !44 {

; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !45 {
; CHECK-NEXT: entry:
; CHECK-NEXT: #dbg_declare(i64 0, !49, !DIExpression(), !58)
; CHECK-NEXT: #dbg_declare(i64 0, !50, !DIExpression(), !58)
; CHECK-NEXT: #dbg_declare(i64 0, !51, !DIExpression(), !58)
; CHECK-NEXT: #dbg_label(!59, !58)
; CHECK-NEXT: #dbg_declare(i64 0, !50, !DIExpression(), !59)
; CHECK-NEXT: #dbg_declare(i64 0, !51, !DIExpression(), !59)
; CHECK-NEXT: #dbg_declare(i64 0, !52, !DIExpression(), !59)
; CHECK-NEXT: #dbg_label(!60, !59)
; CHECK-NEXT: br label %vars
; CHECK-NEXT: #dbg_label(!60, !58)
; CHECK-NEXT: #dbg_label(!61, !59)
; CHECK-NEXT: br label %vars

; CHECK: vars: ; preds = %entry, %entry
; CHECK-NEXT: %p1 = phi i64 [ 0, %entry ]
; CHECK-NEXT: %p2 = phi i64 [ 0, %entry ]
; CHECK-NEXT: #dbg_value(i64 0, !42, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !61)
; CHECK-NEXT: #dbg_value(i64 1, !52, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !61)
; CHECK-NEXT: #dbg_value(i64 0, !43, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !62)
; CHECK-NEXT: #dbg_value(i64 1, !53, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !62)
; CHECK-NEXT: %a = add i64 %p1, %p2
; CHECK-NEXT: ret i64 0
; CHECK-NEXT: }

; CHECK: !llvm.dbg.cu = !{!0}
; CHECK-NEXT: !FooType = !{!33}
; CHECK-NEXT: !FooType = !{!34}
; CHECK-NEXT: !EnumTest = !{!3}
; CHECK-NEXT: !LargeEnumTest = !{!11}
; CHECK-NEXT: !SubrangeType = !{!36}
; CHECK-NEXT: !SetType1 = !{!37}
; CHECK-NEXT: !SetType2 = !{!38}
; CHECK-NEXT: !DynType = !{!39}
; CHECK-NEXT: !ClassType = !{!54}
; CHECK-NEXT: !SubrangeType = !{!37}
; CHECK-NEXT: !SetType1 = !{!38}
; CHECK-NEXT: !SetType2 = !{!39}
; CHECK-NEXT: !DynType = !{!40}
; CHECK-NEXT: !ClassType = !{!55}

; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !16, imports: !24, macros: !28, splitDebugInlining: false, sysroot: "/")
; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !16, imports: !24, macros: !29, splitDebugInlining: false, sysroot: "/")
; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c", directory: ".")
; CHECK-NEXT: !2 = !{!3, !11}
; CHECK-NEXT: !3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EnumTest", scope: !4, file: !1, baseType: !6, size: 64, elements: !7)
Expand All @@ -57,41 +57,42 @@
; CHECK-NEXT: !21 = !DIGlobalVariableExpression(var: !22, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value))
; CHECK-NEXT: !22 = distinct !DIGlobalVariable(name: "global", scope: !5, file: !1, line: 1, type: !23, isLocal: true, isDefinition: true)
; CHECK-NEXT: !23 = !DIDerivedType(tag: DW_TAG_typedef, name: "int64_t", scope: !1, file: !1, line: 42, baseType: !6)
; CHECK-NEXT: !24 = !{!25, !27}
; CHECK-NEXT: !25 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !26, file: !1, line: 42)
; CHECK-NEXT: !24 = !{!25, !28}
; CHECK-NEXT: !25 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !26, file: !27, line: 42)
; CHECK-NEXT: !26 = !DIModule(scope: null, name: "llvm-c-test-import", includePath: "/test/include/llvm-c-test-import.h")
; CHECK-NEXT: !27 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !25, file: !1, line: 42)
; CHECK-NEXT: !28 = !{!29}
; CHECK-NEXT: !29 = !DIMacroFile(file: !1, nodes: !30)
; CHECK-NEXT: !30 = !{!31, !32}
; CHECK-NEXT: !31 = !DIMacro(type: DW_MACINFO_define, name: "SIMPLE_DEFINE")
; CHECK-NEXT: !32 = !DIMacro(type: DW_MACINFO_define, name: "VALUE_DEFINE", value: "1")
; CHECK-NEXT: !33 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !34, size: 192, dwarfAddressSpace: 0)
; CHECK-NEXT: !34 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !4, file: !1, size: 192, elements: !35, runtimeLang: DW_LANG_C89, identifier: "MyStruct")
; CHECK-NEXT: !35 = !{!6, !6, !6}
; CHECK-NEXT: !36 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1, stride: i64 8, bias: i64 4)
; CHECK-NEXT: !37 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64)
; CHECK-NEXT: !38 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !36, size: 64)
; CHECK-NEXT: !39 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !40, dataLocation: !DIExpression(), associated: !42, rank: !DIExpression())
; CHECK-NEXT: !40 = !{!41}
; CHECK-NEXT: !41 = !DISubrange(count: 10, lowerBound: 0)
; CHECK-NEXT: !42 = !DILocalVariable(name: "d", scope: !43, file: !1, line: 43, type: !6)
; CHECK-NEXT: !43 = distinct !DILexicalBlock(scope: !44, file: !1, line: 42)
; CHECK-NEXT: !44 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !45, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !48)
; CHECK-NEXT: !45 = !DISubroutineType(types: !46)
; CHECK-NEXT: !46 = !{!6, !6, !47}
; CHECK-NEXT: !47 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !40)
; CHECK-NEXT: !48 = !{!49, !50, !51, !42, !52, !53}
; CHECK-NEXT: !49 = !DILocalVariable(name: "a", arg: 1, scope: !44, file: !1, line: 42, type: !6)
; CHECK-NEXT: !50 = !DILocalVariable(name: "b", arg: 2, scope: !44, file: !1, line: 42, type: !6)
; CHECK-NEXT: !51 = !DILocalVariable(name: "c", arg: 3, scope: !44, file: !1, line: 42, type: !47)
; CHECK-NEXT: !52 = !DILocalVariable(name: "e", scope: !43, file: !1, line: 44, type: !6)
; CHECK-NEXT: !53 = !DILabel(scope: !44, name: "label3", file: !1, line: 42)
; CHECK-NEXT: !54 = !DICompositeType(tag: DW_TAG_class_type, name: "Class", scope: !4, file: !1, size: 192, flags: DIFlagFwdDecl, elements: !55, identifier: "FooClass")
; CHECK-NEXT: !55 = !{!56}
; CHECK-NEXT: !56 = !{!6, !6, !57}
; CHECK-NEXT: !57 = !DIBasicType(name: "Int32", size: 32)
; CHECK-NEXT: !58 = !DILocation(line: 42, scope: !44)
; CHECK-NEXT: !59 = !DILabel(scope: !44, name: "label1", file: !1, line: 42)
; CHECK-NEXT: !60 = !DILabel(scope: !44, name: "label2", file: !1, line: 42)
; CHECK-NEXT: !61 = !DILocation(line: 43, scope: !44)
; CHECK-NEXT: !27 = !DIFile(filename: "debuginfo.c", directory: ".", checksumkind: CSK_MD5, checksum: "1234", source: "source")
; CHECK-NEXT: !28 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !25, file: !1, line: 42)
; CHECK-NEXT: !29 = !{!30}
; CHECK-NEXT: !30 = !DIMacroFile(file: !1, nodes: !31)
; CHECK-NEXT: !31 = !{!32, !33}
; CHECK-NEXT: !32 = !DIMacro(type: DW_MACINFO_define, name: "SIMPLE_DEFINE")
; CHECK-NEXT: !33 = !DIMacro(type: DW_MACINFO_define, name: "VALUE_DEFINE", value: "1")
; CHECK-NEXT: !34 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !35, size: 192, dwarfAddressSpace: 0)
; CHECK-NEXT: !35 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !4, file: !1, size: 192, elements: !36, runtimeLang: DW_LANG_C89, identifier: "MyStruct")
; CHECK-NEXT: !36 = !{!6, !6, !6}
; CHECK-NEXT: !37 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1, stride: i64 8, bias: i64 4)
; CHECK-NEXT: !38 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64)
; CHECK-NEXT: !39 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !37, size: 64)
; CHECK-NEXT: !40 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !41, dataLocation: !DIExpression(), associated: !43, rank: !DIExpression())
; CHECK-NEXT: !41 = !{!42}
; CHECK-NEXT: !42 = !DISubrange(count: 10, lowerBound: 0)
; CHECK-NEXT: !43 = !DILocalVariable(name: "d", scope: !44, file: !1, line: 43, type: !6)
; CHECK-NEXT: !44 = distinct !DILexicalBlock(scope: !45, file: !1, line: 42)
; CHECK-NEXT: !45 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !46, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !49)
; CHECK-NEXT: !46 = !DISubroutineType(types: !47)
; CHECK-NEXT: !47 = !{!6, !6, !48}
; CHECK-NEXT: !48 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !41)
; CHECK-NEXT: !49 = !{!50, !51, !52, !43, !53, !54}
; CHECK-NEXT: !50 = !DILocalVariable(name: "a", arg: 1, scope: !45, file: !1, line: 42, type: !6)
; CHECK-NEXT: !51 = !DILocalVariable(name: "b", arg: 2, scope: !45, file: !1, line: 42, type: !6)
; CHECK-NEXT: !52 = !DILocalVariable(name: "c", arg: 3, scope: !45, file: !1, line: 42, type: !48)
; CHECK-NEXT: !53 = !DILocalVariable(name: "e", scope: !44, file: !1, line: 44, type: !6)
; CHECK-NEXT: !54 = !DILabel(scope: !45, name: "label3", file: !1, line: 42)
; CHECK-NEXT: !55 = !DICompositeType(tag: DW_TAG_class_type, name: "Class", scope: !4, file: !1, size: 192, flags: DIFlagFwdDecl, elements: !56, identifier: "FooClass")
; CHECK-NEXT: !56 = !{!57}
; CHECK-NEXT: !57 = !{!6, !6, !58}
; CHECK-NEXT: !58 = !DIBasicType(name: "Int32", size: 32)
; CHECK-NEXT: !59 = !DILocation(line: 42, scope: !45)
; CHECK-NEXT: !60 = !DILabel(scope: !45, name: "label1", file: !1, line: 42)
; CHECK-NEXT: !61 = !DILabel(scope: !45, name: "label2", file: !1, line: 42)
; CHECK-NEXT: !62 = !DILocation(line: 43, scope: !45)
5 changes: 4 additions & 1 deletion llvm/tools/llvm-c-test/debuginfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ int llvm_test_dibuilder(void) {
LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, Filename,
strlen(Filename), ".", 1);

LLVMMetadataRef FileCS = LLVMDIBuilderCreateFileWithCheckSum(
DIB, Filename, strlen(Filename), ".", 1, CSK_MD5, "1234", 4, "source", 6);

LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit(
DIB, LLVMDWARFSourceLanguageC, File, "llvm-c-test", 11, 0, NULL, 0, 0,
NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
Expand All @@ -61,7 +64,7 @@ int llvm_test_dibuilder(void) {
"/test/include/llvm-c-test-import.h", 34,
"", 0);
LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule(
DIB, Module, OtherModule, File, 42, NULL, 0);
DIB, Module, OtherModule, FileCS, 42, NULL, 0);
LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule, File,
42, NULL, 0);

Expand Down