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 Jul 20, 2019
1 parent 9561624 commit 0c34b72
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/LLVM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ include("ir.jl")
include("bitcode.jl")
include("transform.jl")
include("debuginfo.jl")
if libllvm_version >= v"8.0.0"
include("dibuilder.jl")
end

include("interop.jl")

Expand Down
149 changes: 149 additions & 0 deletions src/dibuilder.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
export DIBuilder, DICompileUnit, DILexicalBlock, DIFunction

@checked struct DIBuilder
ref::API.LLVMDIBuilderRef
end
reftype(::Type{DIBuilder}) = API.DILLVMDIBuilderRef

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

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

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

function compileunit!(builder::DIBuilder, cu::DICompileUnit)
file = file!(builder, cu.file, cu.dir)
md = API.LLVMDIBuilderCreateCompileUnit(
ref(builder),
cu.language,
ref(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,
)
return Metadata(md)
end

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

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

function lexicalblock!(builder::DIBuilder, scope::Metadata, block::DILexicalBlock)
md = API.LLVMDIBuilerCreateLexicalBlock(
ref(builder),
ref(scope),
ref(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(
ref(builder),
ref(scope),
ref(file),
convert(Cuint, discriminator)
)
Metadata(md)
end

struct DIFunction
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, scope::Metadata, f::DIFunction)
md = API.LLVMDIBuilderCreateFunction(
ref(builder),
ref(scope),
f.name, convert(Csize_t, length(f.name)),
f.linkageName, convert(Csize_t, length(f.linkageName)),
ref(f.file),
f.line,
ref(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(
ref(builder),
name,
convert(Csize_t, length(name)),
convert(UInt64, size),
encoding,
LLVM.API.LLVMDIFlagZero
)
Metadata(md)
end

function pointertype!(builder::DIBuilder, pointee::Metadata, size, as, align=0, name="")
md = LLVM.API.LLVMDIBuilderCreatePointerType(
ref(builder),
ref(pointee),
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(ref(x) for x in (rettype, paramtypes...))
md = LLVM.API.LLVMDIBuilderCreateSubroutineType(
ref(builder),
ref(file),
params,
length(params),
LLVM.API.LLVMDIFlagZero
)
Metadata(md)
end

# TODO: Types
43 changes: 43 additions & 0 deletions test/dibuilder.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@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 = LLVM.file!(dibuilder, "test.jl", "src")
cu = LLVM.compileunit!(dibuilder, LLVM.API.LLVMDWARFSourceLanguageJulia, file, "LLVM.jl Tests", LLVM.False,
"", UInt32(0), "", LLVM.API.LLVMDWARFEmissionFull, UInt32(4), LLVM.False, LLVM.False)

Builder(ctx) do builder
ft = LLVM.FunctionType(LLVM.VoidType(ctx), [LLVM.Int32Type(ctx)])
fn = LLVM.Function(mod, "SomeFunction", ft)

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

md = LLVM.location!(ctx, UInt32(1), UInt32(1), cu) # could also be file
debuglocation!(builder, LLVM.MetadataAsValue(LLVM.API.LLVMMetadataAsValue(LLVM.ref(ctx), md)))
ret!(builder)
end

finalize(dibuilder)
dispose(dibuilder)

fun = functions(mod)["SomeFunction"]
bb = entry(fun)
inst = first(instructions(bb))

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

end

3 changes: 3 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ include("target.jl")
include("targetmachine.jl")
include("datalayout.jl")
include("debuginfo.jl")
if LLVM.version() >= v"8.0.0"
include("dibuilder.jl")
end

include("Kaleidoscope.jl")

Expand Down

0 comments on commit 0c34b72

Please sign in to comment.