Skip to content

Commit

Permalink
support for DIBuilder on LLVM8
Browse files Browse the repository at this point in the history
  • Loading branch information
vchuravy committed Dec 4, 2021
1 parent 72dcad1 commit 92f053a
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 1 deletion.
156 changes: 156 additions & 0 deletions src/dibuilder.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,163 @@
export DIBuilder, DIFile, DICompileUnit, DILexicalBlock, DISubprogram

@checked struct DIBuilder
ref::API.LLVMDIBuilderRef
end

# LLVMCreateDIBuilderDisallowUnresolved
DIBuilder(mod::Module) = DIBuilder(API.LLVMCreateDIBuilder(mod))

dispose(builder::DIBuilder) = API.LLVMDisposeDIBuilder(builder)
finalize(builder::DIBuilder) = API.LLVMDIBuilderFinalize(builder)

Base.unsafe_convert(::Type{API.LLVMDIBuilderRef}, builder::DIBuilder) = builder.ref

struct DIFile
file::String
dir::String
end

struct DICompileUnit
file::Metadata
language::API.LLVMDWARFSourceLanguage
producer::String
sysroot::String
sdk::String
flags::String
optimized::Core.Bool
version::Int
end

function compileunit!(builder::DIBuilder, cu::DICompileUnit)
md = API.LLVMDIBuilderCreateCompileUnit(
builder,
cu.language,
cu.file,
cu.producer, convert(Csize_t, length(cu.producer)),
cu.optimized ? LLVM.True : LLVM.False,
cu.flags, convert(Csize_t, length(cu.flags)),
convert(Cuint, cu.version),
#=SplitName=# C_NULL, 0,
API.LLVMDWARFEmissionFull,
#=DWOId=# 0,
#=SplitDebugInlining=# LLVM.True,
#=DebugInfoForProfiling=# LLVM.False,
cu.sysroot, convert(Csize_t, length(cu.sysroot)),
cu.sdk, convert(Csize_t, length(cu.sdk)),
)
return Metadata(md)
end

function file!(builder::DIBuilder, file::DIFile)
md = API.LLVMDIBuilderCreateFile(
builder,
file.file, convert(Csize_t, length(file.file)),
file.dir, convert(Csize_t, length(file.dir))
)
return Metadata(md)
end

struct DILexicalBlock
file::Metadata
line::Int
column::Int
end

function lexicalblock!(builder::DIBuilder, scope::Metadata, block::DILexicalBlock)
md = API.LLVMDIBuilderCreateLexicalBlock(
builder,
scope,
block.file,
convert(Cuint, block.line),
convert(Cuint, block.column)
)
Metadata(md)
end

function lexicalblock!(builder::DIBuilder, scope::Metadata, file::Metadata, discriminator)
md = API.LLVMDIBuilderCreateLexicalBlockFile(
builder,
scope,
file,
convert(Cuint, discriminator)
)
Metadata(md)
end

struct DISubprogram
name::String
linkageName::String
file::Metadata
line::Int
type::Metadata
localToUnit::Core.Bool
isDefinition::Core.Bool
scopeLine::Int
flags::LLVM.API.LLVMDIFlags
optimized::Core.Bool
end

function subprogram!(builder::DIBuilder, f::DISubprogram)
md = API.LLVMDIBuilderCreateFunction(
builder,
f.file,
f.name, convert(Csize_t, length(f.name)),
f.linkageName, convert(Csize_t, length(f.linkageName)),
f.file,
f.line,
f.type,
f.localToUnit ? LLVM.True : LLVM.False,
f.isDefinition ? LLVM.True : LLVM.False,
convert(Cuint, f.scopeLine),
f.flags,
f.optimized ? LLVM.True : LLVM.False
)
Metadata(md)
end

# TODO: Variables

function basictype!(builder::DIBuilder, name, size, encoding)
md = LLVM.API.LLVMDIBuilderCreateBasicType(
builder,
name, convert(Csize_t, length(name)),
convert(UInt64, size),
encoding,
LLVM.API.LLVMDIFlagZero
)
Metadata(md)
end

function pointertype!(builder::DIBuilder, basetype::Metadata, size, as, align=0, name="")
md = LLVM.API.LLVMDIBuilderCreatePointerType(
builder,
basetype,
convert(UInt64, size),
convert(UInt32, align),
convert(Cuint, as),
name, convert(Csize_t, length(name)),
)
Metadata(md)
end

function subroutinetype!(builder::DIBuilder, file::Metadata, rettype, paramtypes...)
params = collect(x for x in (rettype, paramtypes...))
md = LLVM.API.LLVMDIBuilderCreateSubroutineType(
builder,
file,
params,
length(params),
LLVM.API.LLVMDIFlagZero
)
Metadata(md)
end

function DILocation(ctx, line, col, scope=nothing, inlined_at=nothing)
# XXX: are null scopes valid? they crash LLVM:
# DILocation(Context(), 1, 2).scope
DILocation(API.LLVMDIBuilderCreateDebugLocation(ctx, line, col,
something(scope, C_NULL),
something(inlined_at, C_NULL)))
end

# TODO: Types
69 changes: 69 additions & 0 deletions test/dibuilder.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@testset "dibuilder" begin

Context() do ctx
LLVM.Module("SomeModule", ctx) do mod
builder = DIBuilder(mod)
dispose(builder)
end
end

Context() do ctx
LLVM.Module("SomeModule", ctx) do mod
dibuilder = DIBuilder(mod)
file = DIFile("test.jl", "src")
file_md = LLVM.file!(dibuilder, file)
cu = DICompileUnit(file_md, LLVM.API.LLVMDWARFSourceLanguageJulia, "LLVM.jl Tests", "/", "LLVM.jl", "", false, 4)
cu_md = LLVM.compileunit!(dibuilder, cu)

Builder(ctx) do builder
ft = LLVM.FunctionType(LLVM.VoidType(ctx), [LLVM.Int64Type(ctx)])
rt_md = LLVM.basictype!(dibuilder, "Nothing", 0, 0)
param_md = LLVM.basictype!(dibuilder, "Int64", sizeof(Int64), 0)
dift_md = LLVM.subroutinetype!(dibuilder, file_md, rt_md, param_md)
fn = LLVM.Function(mod, "SomeFunction", ft)
difn = DISubprogram(LLVM.name(fn), "linkage", file_md, 3, dift_md, true, true, 5, LLVM.API.LLVMDIFlagPublic, false)
difn_md = LLVM.subprogram!(dibuilder, difn)
LLVM.set_subprogram!(fn, difn_md)

entrybb = BasicBlock(fn, "entry")
position!(builder, entrybb)

ptr = inttoptr!(builder, parameters(fn)[1], LLVM.PointerType(LLVM.Int64Type(ctx)))
ptr_md = LLVM.pointertype!(dibuilder, param_md, sizeof(Ptr{Int64}), LLVM.addrspace(llvmtype(ptr)), 0, "MyPtr")
# TODO: LLVM.dbg_declare!(builder, mod, ptr, ptr_md)
val = ptrtoint!(builder, ptr, LLVM.Int64Type(ctx))

block = DILexicalBlock(file_md, 1, 1)
block_md = LLVM.lexicalblock!(dibuilder, file_md, block) # could also be file
debuglocation!(builder, LLVM.MetadataAsValue(LLVM.API.LLVMMetadataAsValue(ctx, block_md)))
ret!(builder)
end

finalize(dibuilder)
dispose(dibuilder)

fun = functions(mod)["SomeFunction"]
bb = entry(fun)
inst = last(instructions(bb))
@test !isempty(metadata(inst))
inst_str = sprint(io->Base.show(io, inst))
@test occursin("!dbg", inst_str)

@test !isempty(metadata(inst))
mod_str = sprint(io->Base.show(io, mod))
@test occursin("!llvm.dbg.cu", mod_str)
@test occursin("!DICompileUnit", mod_str)
@test occursin("!DIFile", mod_str)
@test occursin("!DILexicalBlock", mod_str)
@test !occursin("scope: null", mod_str)
@test occursin("DISubprogram", mod_str)
@test occursin("DISubroutineType", mod_str)
@test occursin("DIBasicType", mod_str)

strip_debuginfo!(mod)
@test isempty(metadata(inst))
end
end

end

2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ if LLVM.has_orc_v2()
include("orcv2.jl")
end

include("dibuilder.jl")

include("Kaleidoscope.jl")

include("examples.jl")

include("interop.jl")

end

0 comments on commit 92f053a

Please sign in to comment.