Go bindings: add DIBuilder.InsertValueAtEnd
[oota-llvm.git] / bindings / go / llvm / dibuilder.go
1 //===- dibuilder.go - Bindings for DIBuilder ------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines bindings for the DIBuilder class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 package llvm
15
16 /*
17 #include "DIBuilderBindings.h"
18 #include <stdlib.h>
19 */
20 import "C"
21
22 import (
23         "debug/dwarf"
24         "unsafe"
25 )
26
27 type DwarfTag uint32
28
29 const (
30         DW_TAG_lexical_block   DwarfTag = 0x0b
31         DW_TAG_compile_unit    DwarfTag = 0x11
32         DW_TAG_variable        DwarfTag = 0x34
33         DW_TAG_base_type       DwarfTag = 0x24
34         DW_TAG_pointer_type    DwarfTag = 0x0F
35         DW_TAG_structure_type  DwarfTag = 0x13
36         DW_TAG_subroutine_type DwarfTag = 0x15
37         DW_TAG_file_type       DwarfTag = 0x29
38         DW_TAG_subprogram      DwarfTag = 0x2E
39         DW_TAG_auto_variable   DwarfTag = 0x100
40         DW_TAG_arg_variable    DwarfTag = 0x101
41 )
42
43 const (
44         FlagPrivate = 1 << iota
45         FlagProtected
46         FlagFwdDecl
47         FlagAppleBlock
48         FlagBlockByrefStruct
49         FlagVirtual
50         FlagArtificial
51         FlagExplicit
52         FlagPrototyped
53         FlagObjcClassComplete
54         FlagObjectPointer
55         FlagVector
56         FlagStaticMember
57         FlagIndirectVariable
58 )
59
60 type DwarfLang uint32
61
62 const (
63         // http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open
64         DW_LANG_Go DwarfLang = 0x0016
65 )
66
67 type DwarfTypeEncoding uint32
68
69 const (
70         DW_ATE_address         DwarfTypeEncoding = 0x01
71         DW_ATE_boolean         DwarfTypeEncoding = 0x02
72         DW_ATE_complex_float   DwarfTypeEncoding = 0x03
73         DW_ATE_float           DwarfTypeEncoding = 0x04
74         DW_ATE_signed          DwarfTypeEncoding = 0x05
75         DW_ATE_signed_char     DwarfTypeEncoding = 0x06
76         DW_ATE_unsigned        DwarfTypeEncoding = 0x07
77         DW_ATE_unsigned_char   DwarfTypeEncoding = 0x08
78         DW_ATE_imaginary_float DwarfTypeEncoding = 0x09
79         DW_ATE_packed_decimal  DwarfTypeEncoding = 0x0a
80         DW_ATE_numeric_string  DwarfTypeEncoding = 0x0b
81         DW_ATE_edited          DwarfTypeEncoding = 0x0c
82         DW_ATE_signed_fixed    DwarfTypeEncoding = 0x0d
83         DW_ATE_unsigned_fixed  DwarfTypeEncoding = 0x0e
84         DW_ATE_decimal_float   DwarfTypeEncoding = 0x0f
85         DW_ATE_UTF             DwarfTypeEncoding = 0x10
86         DW_ATE_lo_user         DwarfTypeEncoding = 0x80
87         DW_ATE_hi_user         DwarfTypeEncoding = 0xff
88 )
89
90 // DIBuilder is a wrapper for the LLVM DIBuilder class.
91 type DIBuilder struct {
92         ref C.LLVMDIBuilderRef
93         m   Module
94 }
95
96 // NewDIBuilder creates a new DIBuilder, associated with the given module.
97 func NewDIBuilder(m Module) *DIBuilder {
98         d := C.LLVMNewDIBuilder(m.C)
99         return &DIBuilder{ref: d, m: m}
100 }
101
102 // Destroy destroys the DIBuilder.
103 func (d *DIBuilder) Destroy() {
104         C.LLVMDIBuilderDestroy(d.ref)
105 }
106
107 // FInalize finalizes the debug information generated by the DIBuilder.
108 func (d *DIBuilder) Finalize() {
109         C.LLVMDIBuilderFinalize(d.ref)
110 }
111
112 // DICompileUnit holds the values for creating compile unit debug metadata.
113 type DICompileUnit struct {
114         Language       DwarfLang
115         File           string
116         Dir            string
117         Producer       string
118         Optimized      bool
119         Flags          string
120         RuntimeVersion int
121 }
122
123 // CreateCompileUnit creates compile unit debug metadata.
124 func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Value {
125         file := C.CString(cu.File)
126         defer C.free(unsafe.Pointer(file))
127         dir := C.CString(cu.Dir)
128         defer C.free(unsafe.Pointer(dir))
129         producer := C.CString(cu.Producer)
130         defer C.free(unsafe.Pointer(producer))
131         flags := C.CString(cu.Flags)
132         defer C.free(unsafe.Pointer(flags))
133         result := C.LLVMDIBuilderCreateCompileUnit(
134                 d.ref,
135                 C.unsigned(cu.Language),
136                 file, dir,
137                 producer,
138                 boolToCInt(cu.Optimized),
139                 flags,
140                 C.unsigned(cu.RuntimeVersion),
141         )
142         return Value{C: result}
143 }
144
145 // CreateCompileUnit creates file debug metadata.
146 func (d *DIBuilder) CreateFile(filename, dir string) Value {
147         cfilename := C.CString(filename)
148         defer C.free(unsafe.Pointer(cfilename))
149         cdir := C.CString(dir)
150         defer C.free(unsafe.Pointer(cdir))
151         result := C.LLVMDIBuilderCreateFile(d.ref, cfilename, cdir)
152         return Value{C: result}
153 }
154
155 // DILexicalBlock holds the values for creating lexical block debug metadata.
156 type DILexicalBlock struct {
157         File   Value
158         Line   int
159         Column int
160 }
161
162 // CreateCompileUnit creates lexical block debug metadata.
163 func (d *DIBuilder) CreateLexicalBlock(diScope Value, b DILexicalBlock) Value {
164         result := C.LLVMDIBuilderCreateLexicalBlock(
165                 d.ref,
166                 diScope.C,
167                 b.File.C,
168                 C.unsigned(b.Line),
169                 C.unsigned(b.Column),
170         )
171         return Value{C: result}
172 }
173
174 func (d *DIBuilder) CreateLexicalBlockFile(diScope Value, diFile Value, discriminator int) Value {
175         result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
176                 C.unsigned(discriminator))
177         return Value{C: result}
178 }
179
180 // DIFunction holds the values for creating function debug metadata.
181 type DIFunction struct {
182         Name         string
183         LinkageName  string
184         File         Value
185         Line         int
186         Type         Value
187         LocalToUnit  bool
188         IsDefinition bool
189         ScopeLine    int
190         Flags        int
191         Optimized    bool
192         Function     Value
193 }
194
195 // CreateCompileUnit creates function debug metadata.
196 func (d *DIBuilder) CreateFunction(diScope Value, f DIFunction) Value {
197         name := C.CString(f.Name)
198         defer C.free(unsafe.Pointer(name))
199         linkageName := C.CString(f.LinkageName)
200         defer C.free(unsafe.Pointer(linkageName))
201         result := C.LLVMDIBuilderCreateFunction(
202                 d.ref,
203                 diScope.C,
204                 name,
205                 linkageName,
206                 f.File.C,
207                 C.unsigned(f.Line),
208                 f.Type.C,
209                 boolToCInt(f.LocalToUnit),
210                 boolToCInt(f.IsDefinition),
211                 C.unsigned(f.ScopeLine),
212                 C.unsigned(f.Flags),
213                 boolToCInt(f.Optimized),
214                 f.Function.C,
215         )
216         return Value{C: result}
217 }
218
219 // DILocalVariable holds the values for creating local variable debug metadata.
220 type DILocalVariable struct {
221         Tag            dwarf.Tag
222         Name           string
223         File           Value
224         Line           int
225         Type           Value
226         AlwaysPreserve bool
227         Flags          int
228
229         // ArgNo is the 1-based index of the argument in the function's
230         // parameter list if it is an argument, or 0 otherwise.
231         ArgNo int
232 }
233
234 // CreateLocalVariable creates local variable debug metadata.
235 func (d *DIBuilder) CreateLocalVariable(scope Value, v DILocalVariable) Value {
236         name := C.CString(v.Name)
237         defer C.free(unsafe.Pointer(name))
238         result := C.LLVMDIBuilderCreateLocalVariable(
239                 d.ref,
240                 C.unsigned(v.Tag),
241                 scope.C,
242                 name,
243                 v.File.C,
244                 C.unsigned(v.Line),
245                 v.Type.C,
246                 boolToCInt(v.AlwaysPreserve),
247                 C.unsigned(v.Flags),
248                 C.unsigned(v.ArgNo),
249         )
250         return Value{C: result}
251 }
252
253 // DIBasicType holds the values for creating basic type debug metadata.
254 type DIBasicType struct {
255         Name        string
256         SizeInBits  uint64
257         AlignInBits uint64
258         Encoding    DwarfTypeEncoding
259 }
260
261 // CreateBasicType creates basic type debug metadata.
262 func (d *DIBuilder) CreateBasicType(t DIBasicType) Value {
263         name := C.CString(t.Name)
264         defer C.free(unsafe.Pointer(name))
265         result := C.LLVMDIBuilderCreateBasicType(
266                 d.ref,
267                 name,
268                 C.uint64_t(t.SizeInBits),
269                 C.uint64_t(t.AlignInBits),
270                 C.unsigned(t.Encoding),
271         )
272         return Value{C: result}
273 }
274
275 // DIPointerType holds the values for creating pointer type debug metadata.
276 type DIPointerType struct {
277         Pointee     Value
278         SizeInBits  uint64
279         AlignInBits uint64 // optional
280         Name        string // optional
281 }
282
283 // CreateBasicType creates basic type debug metadata.
284 func (d *DIBuilder) CreatePointerType(t DIPointerType) Value {
285         name := C.CString(t.Name)
286         defer C.free(unsafe.Pointer(name))
287         result := C.LLVMDIBuilderCreatePointerType(
288                 d.ref,
289                 t.Pointee.C,
290                 C.uint64_t(t.SizeInBits),
291                 C.uint64_t(t.AlignInBits),
292                 name,
293         )
294         return Value{C: result}
295 }
296
297 // DISubroutineType holds the values for creating subroutine type debug metadata.
298 type DISubroutineType struct {
299         // File is the file in which the subroutine type is defined.
300         File Value
301
302         // Parameters contains the subroutine parameter types,
303         // including the return type at the 0th index.
304         Parameters []Value
305 }
306
307 // CreateSubroutineType creates subroutine type debug metadata.
308 func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Value {
309         params := d.getOrCreateTypeArray(t.Parameters)
310         result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
311         return Value{C: result}
312 }
313
314 // DIStructType holds the values for creating struct type debug metadata.
315 type DIStructType struct {
316         Name        string
317         File        Value
318         Line        int
319         SizeInBits  uint64
320         AlignInBits uint64
321         Flags       int
322         DerivedFrom Value
323         Elements    []Value
324 }
325
326 // CreateStructType creates struct type debug metadata.
327 func (d *DIBuilder) CreateStructType(scope Value, t DIStructType) Value {
328         elements := d.getOrCreateArray(t.Elements)
329         name := C.CString(t.Name)
330         defer C.free(unsafe.Pointer(name))
331         result := C.LLVMDIBuilderCreateStructType(
332                 d.ref,
333                 scope.C,
334                 name,
335                 t.File.C,
336                 C.unsigned(t.Line),
337                 C.uint64_t(t.SizeInBits),
338                 C.uint64_t(t.AlignInBits),
339                 C.unsigned(t.Flags),
340                 t.DerivedFrom.C,
341                 elements.C,
342         )
343         return Value{C: result}
344 }
345
346 // DIMemberType holds the values for creating member type debug metadata.
347 type DIMemberType struct {
348         Name         string
349         File         Value
350         Line         int
351         SizeInBits   uint64
352         AlignInBits  uint64
353         OffsetInBits uint64
354         Flags        int
355         Type         Value
356 }
357
358 // CreateMemberType creates struct type debug metadata.
359 func (d *DIBuilder) CreateMemberType(scope Value, t DIMemberType) Value {
360         name := C.CString(t.Name)
361         defer C.free(unsafe.Pointer(name))
362         result := C.LLVMDIBuilderCreateMemberType(
363                 d.ref,
364                 scope.C,
365                 name,
366                 t.File.C,
367                 C.unsigned(t.Line),
368                 C.uint64_t(t.SizeInBits),
369                 C.uint64_t(t.AlignInBits),
370                 C.uint64_t(t.OffsetInBits),
371                 C.unsigned(t.Flags),
372                 t.Type.C,
373         )
374         return Value{C: result}
375 }
376
377 // DISubrange describes an integer value range.
378 type DISubrange struct {
379         Lo    int64
380         Count int64
381 }
382
383 // DIArrayType holds the values for creating array type debug metadata.
384 type DIArrayType struct {
385         SizeInBits  uint64
386         AlignInBits uint64
387         ElementType Value
388         Subscripts  []DISubrange
389 }
390
391 // CreateArrayType creates struct type debug metadata.
392 func (d *DIBuilder) CreateArrayType(t DIArrayType) Value {
393         subscriptsSlice := make([]Value, len(t.Subscripts))
394         for i, s := range t.Subscripts {
395                 subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
396         }
397         subscripts := d.getOrCreateArray(subscriptsSlice)
398         result := C.LLVMDIBuilderCreateArrayType(
399                 d.ref,
400                 C.uint64_t(t.SizeInBits),
401                 C.uint64_t(t.AlignInBits),
402                 t.ElementType.C,
403                 subscripts.C,
404         )
405         return Value{C: result}
406 }
407
408 // DITypedef holds the values for creating typedef type debug metadata.
409 type DITypedef struct {
410         Type    Value
411         Name    string
412         File    Value
413         Line    int
414         Context Value
415 }
416
417 // CreateTypedef creates typedef type debug metadata.
418 func (d *DIBuilder) CreateTypedef(t DITypedef) Value {
419         name := C.CString(t.Name)
420         defer C.free(unsafe.Pointer(name))
421         result := C.LLVMDIBuilderCreateTypedef(
422                 d.ref,
423                 t.Type.C,
424                 name,
425                 t.File.C,
426                 C.unsigned(t.Line),
427                 t.Context.C,
428         )
429         return Value{C: result}
430 }
431
432 // getOrCreateSubrange gets a metadata node for the specified subrange,
433 // creating if required.
434 func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Value {
435         result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
436         return Value{C: result}
437 }
438
439 // getOrCreateArray gets a metadata node containing the specified values,
440 // creating if required.
441 func (d *DIBuilder) getOrCreateArray(values []Value) Value {
442         if len(values) == 0 {
443                 return Value{}
444         }
445         var data *C.LLVMValueRef
446         length := len(values)
447         if length > 0 {
448                 data = &values[0].C
449         }
450         result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
451         return Value{C: result}
452 }
453
454 // getOrCreateTypeArray gets a metadata node for a type array containing the
455 // specified values, creating if required.
456 func (d *DIBuilder) getOrCreateTypeArray(values []Value) Value {
457         if len(values) == 0 {
458                 return Value{}
459         }
460         var data *C.LLVMValueRef
461         length := len(values)
462         if length > 0 {
463                 data = &values[0].C
464         }
465         result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
466         return Value{C: result}
467 }
468
469 // CreateExpression creates a new descriptor for the specified
470 // variable which has a complex address expression for its address.
471 func (d *DIBuilder) CreateExpression(addr []int64) Value {
472         var data *C.int64_t
473         if len(addr) > 0 {
474                 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
475         }
476         result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
477         return Value{C: result}
478 }
479
480 // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
481 // specified basic block for the given value and associated debug metadata.
482 func (d *DIBuilder) InsertDeclareAtEnd(v, diVarInfo, expr Value, bb BasicBlock) Value {
483         result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
484         return Value{C: result}
485 }
486
487 // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
488 // specified basic block for the given value and associated debug metadata.
489 func (d *DIBuilder) InsertValueAtEnd(v, diVarInfo, expr Value, offset uint64, bb BasicBlock) Value {
490         result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, C.uint64_t(offset), diVarInfo.C, expr.C, bb.C)
491         return Value{C: result}
492 }
493
494 func boolToCInt(v bool) C.int {
495         if v {
496                 return 1
497         }
498         return 0
499 }