Skip to content

Commit 223d211

Browse files
authored
Merge pull request #313 from maleadt/tb/dev
Small improvements
2 parents 4ef26c4 + fdf11d2 commit 223d211

File tree

6 files changed

+81
-25
lines changed

6 files changed

+81
-25
lines changed

src/core/context.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,5 @@ end
107107

108108
function _install_handlers()
109109
handler = @cfunction(handle_error, Cvoid, (Cstring,))
110-
111-
# NOTE: LLVM doesn't support re-installing the error handler, which happens when we
112-
# `reload("LLVM")`, so reset it instead. This isn't correct, as the installed
113-
# handler might not have been ours. Ideally we'd have module finalizers...
114-
API.LLVMResetFatalErrorHandler()
115110
API.LLVMInstallFatalErrorHandler(handler)
116111
end

src/core/type.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ export LLVMType, issized, context, show
44
abstract type LLVMType end
55

66
Base.eltype(typ::LLVMType) = Any
7+
Base.sizeof(typ::LLVMType) = error("LLVM types are not sized")
8+
# TODO: expose LLVMSizeOf/LLVMAlignOf, yielding run-time values?
9+
# XXX: can we query type sizes from the data layout or target?
710

811
Base.unsafe_convert(::Type{API.LLVMTypeRef}, typ::LLVMType) = typ.ref
912

src/core/value.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@ function Value(ref::API.LLVMValueRef)
3737
end
3838

3939

40-
4140
## general APIs
4241

4342
export llvmtype, llvmeltype, name, name!, replace_uses!, replace_metadata_uses!, isconstant, isundef, ispoison, context
4443

4544
llvmtype(val::Value) = LLVMType(API.LLVMTypeOf(val))
4645
llvmeltype(val::Value) = eltype(llvmtype(val))
4746

47+
# defer size queries to the LLVM type (where we'll error)
48+
Base.sizeof(val::Value) = sizeof(llvmtype(val))
49+
4850
name(val::Value) = unsafe_string(API.LLVMGetValueName(val))
4951
name!(val::Value, name::String) = API.LLVMSetValueName(val, name)
5052

src/debuginfo.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ function file(var::DIVariable)
5050
ref == C_NULL ? nothing : Metadata(ref)::DIFile
5151
end
5252

53+
function scope(var::DIVariable)
54+
ref = API.LLVMDIVariableGetScope(var)
55+
ref == C_NULL ? nothing : Metadata(ref)::DIScope
56+
end
57+
5358
line(var::DIVariable) = Int(API.LLVMDIVariableGetLine(var))
5459

5560

@@ -64,6 +69,7 @@ file(scope::DIScope) = DIFile(API.LLVMDIScopeGetFile(scope))
6469
function name(scope::DIScope)
6570
len = Ref{Cuint}()
6671
data = API.LLVMExtraDIScopeGetName(scope, len)
72+
data == C_NULL && return nothing
6773
unsafe_string(convert(Ptr{Int8}, data), len[])
6874
end
6975

@@ -82,18 +88,21 @@ register(DIFile, API.LLVMDIFileMetadataKind)
8288
function directory(file::DIFile)
8389
len = Ref{Cuint}()
8490
data = API.LLVMDIFileGetDirectory(file, len)
91+
data == C_NULL && return nothing
8592
unsafe_string(convert(Ptr{Int8}, data), len[])
8693
end
8794

8895
function filename(file::DIFile)
8996
len = Ref{Cuint}()
9097
data = API.LLVMDIFileGetFilename(file, len)
98+
data == C_NULL && return nothing
9199
unsafe_string(convert(Ptr{Int8}, data), len[])
92100
end
93101

94102
function source(file::DIFile)
95103
len = Ref{Cuint}()
96104
data = API.LLVMDIFileGetSource(file, len)
105+
data == C_NULL && return nothing
97106
unsafe_string(convert(Ptr{Int8}, data), len[])
98107
end
99108

@@ -118,6 +127,7 @@ end
118127
function name(typ::DIType)
119128
len = Ref{Csize_t}()
120129
data = API.LLVMDITypeGetName(typ, len)
130+
data == C_NULL && return nothing
121131
unsafe_string(convert(Ptr{Int8}, data), len[])
122132
end
123133

test/core.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ end
4848

4949
@test issized(LLVM.Int1Type(ctx))
5050
@test !issized(LLVM.VoidType(ctx))
51+
@test_throws ErrorException sizeof(typ)
5152
end
5253

5354
# integer
@@ -216,6 +217,7 @@ end
216217
show(devnull, val)
217218

218219
@test llvmtype(val) == LLVM.PointerType(typ)
220+
@test_throws ErrorException sizeof(val)
219221
@test name(val) == "foo"
220222
@test !isconstant(val)
221223
@test !isundef(val)

test/debuginfo.jl

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,58 @@
1+
using LLVM,Test
2+
13
@testset "debuginfo" begin
24

35
DEBUG_METADATA_VERSION()
46

57
@dispose ctx=Context() begin
68
mod = parse(LLVM.Module, """
7-
define void @foo() !dbg !5 {
8-
top:
9-
ret void, !dbg !7
9+
define void @foo() !dbg !15 {
10+
%1 = alloca i32, align 4
11+
call void @llvm.dbg.declare(metadata i32* %1, metadata !19, metadata !DIExpression()), !dbg !21
12+
store i32 0, i32* %1, align 4, !dbg !21
13+
ret void, !dbg !22
1014
}
1115
1216
define void @bar() {
13-
top:
14-
ret void
17+
ret void;
1518
}
1619
17-
!llvm.module.flags = !{!0, !1}
18-
!llvm.dbg.cu = !{!2}
20+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
21+
22+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10}
23+
!llvm.dbg.cu = !{!11}
24+
!llvm.ident = !{!14}
1925
20-
!0 = !{i32 2, !"Dwarf Version", i32 4}
21-
!1 = !{i32 1, !"Debug Info Version", i32 3}
22-
!2 = distinct !DICompileUnit(language: DW_LANG_C89, file: !3, producer: "julia", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4)
23-
!3 = !DIFile(filename: "REPL[1]", directory: ".")
24-
!4 = !{}
25-
!5 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !2)
26-
!6 = !DISubroutineType(types: !4)
27-
!7 = !DILocation(line: 1, scope: !5)"""; ctx)
26+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 12, i32 3]}
27+
!1 = !{i32 7, !"Dwarf Version", i32 4}
28+
!2 = !{i32 2, !"Debug Info Version", i32 3}
29+
!3 = !{i32 1, !"wchar_size", i32 4}
30+
!4 = !{i32 1, !"branch-target-enforcement", i32 0}
31+
!5 = !{i32 1, !"sign-return-address", i32 0}
32+
!6 = !{i32 1, !"sign-return-address-all", i32 0}
33+
!7 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
34+
!8 = !{i32 7, !"PIC Level", i32 2}
35+
!9 = !{i32 7, !"uwtable", i32 1}
36+
!10 = !{i32 7, !"frame-pointer", i32 1}
37+
!11 = distinct !DICompileUnit(language: DW_LANG_C99, file: !12, producer: "Apple clang version 13.1.6 (clang-1316.0.21.2.5)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !13, splitDebugInlining: false, nameTableKind: None, sysroot: "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk", sdk: "MacOSX.sdk")
38+
!12 = !DIFile(filename: "/tmp/test.c", directory: "/Users/tim/Julia/pkg/LLVM")
39+
!13 = !{}
40+
!14 = !{!"Apple clang version 13.1.6 (clang-1316.0.21.2.5)"}
41+
!15 = distinct !DISubprogram(name: "foo", scope: !16, file: !16, line: 1, type: !17, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !11, retainedNodes: !13)
42+
!16 = !DIFile(filename: "test.c", directory: "/tmp")
43+
!17 = !DISubroutineType(types: !18)
44+
!18 = !{null}
45+
!19 = !DILocalVariable(name: "foobar", scope: !15, file: !16, line: 2, type: !20)
46+
!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
47+
!21 = !DILocation(line: 2, column: 9, scope: !15)
48+
!22 = !DILocation(line: 3, column: 5, scope: !15)"""; ctx)
2849

2950
foo = functions(mod)["foo"]
3051

3152
if LLVM.version() >= v"8.0"
3253
sp = LLVM.get_subprogram(foo)
3354
@test sp !== nothing
55+
@test LLVM.line(sp) == 1
3456

3557
bar = functions(mod)["bar"]
3658
@test LLVM.get_subprogram(bar) === nothing
@@ -39,11 +61,33 @@ DEBUG_METADATA_VERSION()
3961
end
4062

4163
bb = entry(foo)
42-
inst = first(instructions(bb))
4364

44-
@test !isempty(metadata(inst))
45-
strip_debuginfo!(mod)
46-
@test isempty(metadata(inst))
65+
let inst = collect(instructions(bb))[2]
66+
diloc = metadata(inst)[LLVM.MD_dbg]::LLVM.DILocation
67+
@test LLVM.line(diloc) == 2
68+
@test LLVM.column(diloc) == 9
69+
@test LLVM.inlined_at(diloc) === nothing
70+
71+
discope = LLVM.scope(diloc)::LLVM.DIScope
72+
@test LLVM.name(discope) == "foo"
73+
74+
difile = LLVM.file(discope)::LLVM.DIFile
75+
@test LLVM.directory(difile) == "/tmp"
76+
@test LLVM.filename(difile) == "test.c"
77+
@test LLVM.source(difile) == ""
78+
79+
divar = Metadata(operands(inst)[2])::LLVM.DILocalVariable
80+
@test LLVM.line(divar) == 2
81+
@test LLVM.file(divar) == difile
82+
@test LLVM.scope(divar) == discope
83+
# TODO: get type and test DIType
84+
end
85+
86+
let inst = collect(instructions(bb))[3]
87+
@test !isempty(metadata(inst))
88+
strip_debuginfo!(mod)
89+
@test isempty(metadata(inst))
90+
end
4791
end
4892

4993
end

0 commit comments

Comments
 (0)