Skip to content

Commit 0c34b72

Browse files
committed
support for DIBuilder on LLVM8
1 parent 9561624 commit 0c34b72

File tree

4 files changed

+198
-0
lines changed

4 files changed

+198
-0
lines changed

src/LLVM.jl

+3
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ include("ir.jl")
122122
include("bitcode.jl")
123123
include("transform.jl")
124124
include("debuginfo.jl")
125+
if libllvm_version >= v"8.0.0"
126+
include("dibuilder.jl")
127+
end
125128

126129
include("interop.jl")
127130

src/dibuilder.jl

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
export DIBuilder, DICompileUnit, DILexicalBlock, DIFunction
2+
3+
@checked struct DIBuilder
4+
ref::API.LLVMDIBuilderRef
5+
end
6+
reftype(::Type{DIBuilder}) = API.DILLVMDIBuilderRef
7+
8+
# LLVMCreateDIBuilderDisallowUnresolved
9+
DIBuilder(mod::Module) = DIBuilder(API.LLVMCreateDIBuilder(ref(mod)))
10+
11+
dispose(builder::DIBuilder) = API.LLVMDisposeDIBuilder(ref(builder))
12+
finalize(builder::DIBuilder) = API.LLVMDIBuilderFinalize(ref(builder))
13+
14+
struct DICompileUnit
15+
file::String
16+
dir::String
17+
language::API.LLVMDWARFSourceLanguage
18+
producer::String
19+
flags::String
20+
optimized::Core.Bool
21+
version::Int
22+
end
23+
24+
function compileunit!(builder::DIBuilder, cu::DICompileUnit)
25+
file = file!(builder, cu.file, cu.dir)
26+
md = API.LLVMDIBuilderCreateCompileUnit(
27+
ref(builder),
28+
cu.language,
29+
ref(file),
30+
cu.producer, convert(Csize_t, length(cu.producer)),
31+
cu.optimized ? LLVM.True : LLVM.False,
32+
cu.flags, convert(Csize_t, length(cu.flags)),
33+
convert(Cuint, cu.version),
34+
#=SplitName=# C_NULL, 0,
35+
API.LLVMDWARFEmissionFull,
36+
#=DWOId=# 0,
37+
#=SplitDebugInlining=# LLVM.True,
38+
#=DebugInfoForProfiling=# LLVM.False,
39+
)
40+
return Metadata(md)
41+
end
42+
43+
function file!(builder::DIBuilder, filename, directory)
44+
md = API.LLVMDIBuilderCreateFile(
45+
ref(builder),
46+
filename, convert(Csize_t, length(filename)),
47+
directory, convert(Csize_t, length(directory))
48+
)
49+
return Metadata(md)
50+
end
51+
52+
struct DILexicalBlock
53+
file::Metadata
54+
line::Int
55+
column::Int
56+
end
57+
58+
function lexicalblock!(builder::DIBuilder, scope::Metadata, block::DILexicalBlock)
59+
md = API.LLVMDIBuilerCreateLexicalBlock(
60+
ref(builder),
61+
ref(scope),
62+
ref(block.file),
63+
convert(Cuint, block.line),
64+
convert(Cuint, block.column)
65+
)
66+
Metadata(md)
67+
end
68+
69+
function lexicalblock!(builder::DIBuilder, scope::Metadata, file::Metadata, discriminator)
70+
md = API.LLVMDIBuilderCreateLexicalBlockFile(
71+
ref(builder),
72+
ref(scope),
73+
ref(file),
74+
convert(Cuint, discriminator)
75+
)
76+
Metadata(md)
77+
end
78+
79+
struct DIFunction
80+
name::String
81+
linkageName::String
82+
file::Metadata
83+
line::Int
84+
type::Metadata
85+
localToUnit::Core.Bool
86+
isDefinition::Core.Bool
87+
scopeLine::Int
88+
flags::LLVM.API.LLVMDIFlags
89+
optimized::Core.Bool
90+
end
91+
92+
function subprogram!(builder::DIBuilder, scope::Metadata, f::DIFunction)
93+
md = API.LLVMDIBuilderCreateFunction(
94+
ref(builder),
95+
ref(scope),
96+
f.name, convert(Csize_t, length(f.name)),
97+
f.linkageName, convert(Csize_t, length(f.linkageName)),
98+
ref(f.file),
99+
f.line,
100+
ref(f.type),
101+
f.localToUnit ? LLVM.True : LLVM.False,
102+
f.isDefinition ? LLVM.True : LLVM.False,
103+
convert(Cuint, f.scopeLine),
104+
f.flags,
105+
f.optimized ? LLVM.True : LLVM.False
106+
)
107+
Metadata(md)
108+
end
109+
110+
# TODO: Variables
111+
112+
function basictype!(builder::DIBuilder, name, size, encoding)
113+
md = LLVM.API.LLVMDIBuilderCreateBasicType(
114+
ref(builder),
115+
name,
116+
convert(Csize_t, length(name)),
117+
convert(UInt64, size),
118+
encoding,
119+
LLVM.API.LLVMDIFlagZero
120+
)
121+
Metadata(md)
122+
end
123+
124+
function pointertype!(builder::DIBuilder, pointee::Metadata, size, as, align=0, name="")
125+
md = LLVM.API.LLVMDIBuilderCreatePointerType(
126+
ref(builder),
127+
ref(pointee),
128+
convert(UInt64, size),
129+
convert(UInt32, align),
130+
convert(Cuint, as),
131+
name,
132+
convert(Csize_t, length(name)),
133+
)
134+
Metadata(md)
135+
end
136+
137+
function subroutinetype!(builder::DIBuilder, file::Metadata, rettype, paramtypes...)
138+
params = collect(ref(x) for x in (rettype, paramtypes...))
139+
md = LLVM.API.LLVMDIBuilderCreateSubroutineType(
140+
ref(builder),
141+
ref(file),
142+
params,
143+
length(params),
144+
LLVM.API.LLVMDIFlagZero
145+
)
146+
Metadata(md)
147+
end
148+
149+
# TODO: Types

test/dibuilder.jl

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
@testset "dibuilder" begin
2+
3+
Context() do ctx
4+
LLVM.Module("SomeModule", ctx) do mod
5+
builder = DIBuilder(mod)
6+
dispose(builder)
7+
end
8+
end
9+
10+
Context() do ctx
11+
LLVM.Module("SomeModule", ctx) do mod
12+
dibuilder = DIBuilder(mod)
13+
file = LLVM.file!(dibuilder, "test.jl", "src")
14+
cu = LLVM.compileunit!(dibuilder, LLVM.API.LLVMDWARFSourceLanguageJulia, file, "LLVM.jl Tests", LLVM.False,
15+
"", UInt32(0), "", LLVM.API.LLVMDWARFEmissionFull, UInt32(4), LLVM.False, LLVM.False)
16+
17+
Builder(ctx) do builder
18+
ft = LLVM.FunctionType(LLVM.VoidType(ctx), [LLVM.Int32Type(ctx)])
19+
fn = LLVM.Function(mod, "SomeFunction", ft)
20+
21+
entrybb = BasicBlock(fn, "entry")
22+
position!(builder, entrybb)
23+
24+
md = LLVM.location!(ctx, UInt32(1), UInt32(1), cu) # could also be file
25+
debuglocation!(builder, LLVM.MetadataAsValue(LLVM.API.LLVMMetadataAsValue(LLVM.ref(ctx), md)))
26+
ret!(builder)
27+
end
28+
29+
finalize(dibuilder)
30+
dispose(dibuilder)
31+
32+
fun = functions(mod)["SomeFunction"]
33+
bb = entry(fun)
34+
inst = first(instructions(bb))
35+
36+
@test !isempty(metadata(inst))
37+
strip_debuginfo!(mod)
38+
@test isempty(metadata(inst))
39+
end
40+
end
41+
42+
end
43+

test/runtests.jl

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ include("target.jl")
5757
include("targetmachine.jl")
5858
include("datalayout.jl")
5959
include("debuginfo.jl")
60+
if LLVM.version() >= v"8.0.0"
61+
include("dibuilder.jl")
62+
end
6063

6164
include("Kaleidoscope.jl")
6265

0 commit comments

Comments
 (0)