- support DICompileUnit
- support DIFIle
- support DISubroutine
- support DIBasicType
- support DILocation
- added gradle build
- debug info bindings are involved in kotlin build
- added binding to DIGetSubprogramLinkName
- added binding to LLVMBuilderGetCurrentFunction
- added reset location
- simple demo added (buildable with gradle)
produces folowing output:
Following pseudo code in sources.
0:123456789012345678901
1: fun main():Int {
2: {foo()}()
3: return 0
4: }
5 fun foo() {}
0:b-backend-dwarf:minamoto@unit-703(0)# ./demo
; ModuleID = 'test'
source_filename = "test"
define i32 @foo(i32) !dbg !3 {
entry:
ret i32 %0, !dbg !7
}
!llvm.dbg.cu = !{!0}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "konanc", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "1.kt", directory: "src")
!2 = !{}
!3 = distinct !DISubprogram(name: "foo", linkageName: "foo:link", scope: null, file: !1, line: 66, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, align: 4)
!7 = !DILocation(line: 42, column: 15, scope: !3)
- demo sharing debug information between several bitcode artifacts
0:b-backend-dwarf:minamoto@unit-703(0)# llvmDebugInfoC/build/exe/demogenerated/demogenerated
; ModuleID = 'test'
source_filename = "test"
define void @foo() !dbg !3 {
entry:
ret void, !dbg !5
}
define void @"main$caller$foo"() !dbg !6 {
entry:
call void @foo(), !dbg !7
ret void
}
define void @main() !dbg !8 {
entry:
call void @"main$caller$foo"(), !dbg !9
ret void, !dbg !10
}
!llvm.dbg.cu = !{!0}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "konanc", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "<stdin>", directory: "")
!2 = !{}
!3 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 5, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
!4 = !DISubroutineType(types: !2)
!5 = !DILocation(line: 5, column: 14, scope: !3)
!6 = distinct !DISubprogram(name: "main$caller$foo", linkageName: "main$caller$foo", scope: null, file: !1, line: 2, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
!7 = !DILocation(line: 5, column: 2, scope: !6)
!8 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !1, line: 1, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
!9 = !DILocation(line: 2, column: 12, scope: !8)
!10 = !DILocation(line: 3, column: 4, scope: !8)
- local variables support
- demo for local variable suppor (TBD some out put here).
; ModuleID = 'test'
source_filename = "test"
define i32 @main() !dbg !3 {
entry:
%0 = alloca i32
call void @llvm.dbg.declare(metadata i32* %0, metadata !5, metadata !7), !dbg !8
store i32 42, i32* %0, !dbg !8
%1 = load i32, i32* %0, !dbg !8
ret i32 %1, !dbg !8
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
attributes #0 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "konanc", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "<stdin>", directory: "")
!2 = !{}
!3 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !1, line: 1, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
!4 = !DISubroutineType(types: !2)
!5 = !DILocalVariable(name: "a", scope: !3, file: !1, line: 2, type: !6)
!6 = !DIBasicType(name: "int", size: 32, align: 4)
!7 = !DIExpression()
!8 = !DILocation(line: 2, column: 1, scope: !3)
Kotlin/Native
Kotlin/Native is a LLVM backend for the Kotlin compiler, runtime implementation and native code generation facility using LLVM toolchain.
Kotlin/Native is primarily designed to allow compilation for platforms where virtual machines are not desirable or possible (such as iOS, embedded targets), or where developer is willing to produce reasonably-sized self-contained program without need to ship an additional execution runtime.
To compile from sources use following steps.
First download dependencies:
./gradlew dependencies:update
Then build the compiler and standard library:
./gradlew dist
To build standard library for cross-targets (currently, iOS on Mac OSX and Raspberry Pi on Linux hosts) use:
./gradlew cross_dist
After that you should be able to compile your programs like that:
export PATH=./dist/bin:$PATH
kotlinc hello.kt -o hello
For an optimized compilation use -opt:
kotlinc hello.kt -o hello -opt
For some tests, use:
./gradlew backend.native:tests:run
To generate interoperability stubs create library definition file
(take a look on samples/tetris/sdl.def) and run cinterop tool like this:
cinterop -def lib.def
See provided samples and INTEROP.md for more details.