[bindings] Update Go bindings to DIBuilder
[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) Metadata {
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 Metadata{C: result}
143 }
144
145 // CreateCompileUnit creates file debug metadata.
146 func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
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 Metadata{C: result}
153 }
154
155 // DILexicalBlock holds the values for creating lexical block debug metadata.
156 type DILexicalBlock struct {
157         File   Metadata
158         Line   int
159         Column int
160 }
161
162 // CreateCompileUnit creates lexical block debug metadata.
163 func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
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 Metadata{C: result}
172 }
173
174 func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata {
175         result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
176                 C.unsigned(discriminator))
177         return Metadata{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         Metadata
185         Line         int
186         Type         Metadata
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 Metadata, f DIFunction) Metadata {
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 Metadata{C: result}
217 }
218
219 // DIAutoVariable holds the values for creating auto variable debug metadata.
220 type DIAutoVariable struct {
221         Name           string
222         File           Metadata
223         Line           int
224         Type           Metadata
225         AlwaysPreserve bool
226         Flags          int
227 }
228
229 // CreateAutoVariable creates local variable debug metadata.
230 func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
231         name := C.CString(v.Name)
232         defer C.free(unsafe.Pointer(name))
233         result := C.LLVMDIBuilderCreateAutoVariable(
234                 d.ref,
235                 scope.C,
236                 name,
237                 v.File.C,
238                 C.unsigned(v.Line),
239                 v.Type.C,
240                 boolToCInt(v.AlwaysPreserve),
241                 C.unsigned(v.Flags),
242         )
243         return Metadata{C: result}
244 }
245
246 // DIParameterVariable holds the values for creating parameter variable debug metadata.
247 type DIParameterVariable struct {
248         Name           string
249         File           Metadata
250         Line           int
251         Type           Metadata
252         AlwaysPreserve bool
253         Flags          int
254
255         // ArgNo is the 1-based index of the argument in the function's
256         // parameter list.
257         ArgNo int
258 }
259
260 // CreateParameterVariable creates parameter variable debug metadata.
261 func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
262         name := C.CString(v.Name)
263         defer C.free(unsafe.Pointer(name))
264         result := C.LLVMDIBuilderCreateParameterVariable(
265                 d.ref,
266                 scope.C,
267                 name,
268                 C.unsigned(v.ArgNo),
269                 v.File.C,
270                 C.unsigned(v.Line),
271                 v.Type.C,
272                 boolToCInt(v.AlwaysPreserve),
273                 C.unsigned(v.Flags),
274         )
275         return Metadata{C: result}
276 }
277
278 // DIBasicType holds the values for creating basic type debug metadata.
279 type DIBasicType struct {
280         Name        string
281         SizeInBits  uint64
282         AlignInBits uint64
283         Encoding    DwarfTypeEncoding
284 }
285
286 // CreateBasicType creates basic type debug metadata.
287 func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
288         name := C.CString(t.Name)
289         defer C.free(unsafe.Pointer(name))
290         result := C.LLVMDIBuilderCreateBasicType(
291                 d.ref,
292                 name,
293                 C.uint64_t(t.SizeInBits),
294                 C.uint64_t(t.AlignInBits),
295                 C.unsigned(t.Encoding),
296         )
297         return Metadata{C: result}
298 }
299
300 // DIPointerType holds the values for creating pointer type debug metadata.
301 type DIPointerType struct {
302         Pointee     Metadata
303         SizeInBits  uint64
304         AlignInBits uint64 // optional
305         Name        string // optional
306 }
307
308 // CreateBasicType creates basic type debug metadata.
309 func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
310         name := C.CString(t.Name)
311         defer C.free(unsafe.Pointer(name))
312         result := C.LLVMDIBuilderCreatePointerType(
313                 d.ref,
314                 t.Pointee.C,
315                 C.uint64_t(t.SizeInBits),
316                 C.uint64_t(t.AlignInBits),
317                 name,
318         )
319         return Metadata{C: result}
320 }
321
322 // DISubroutineType holds the values for creating subroutine type debug metadata.
323 type DISubroutineType struct {
324         // File is the file in which the subroutine type is defined.
325         File Metadata
326
327         // Parameters contains the subroutine parameter types,
328         // including the return type at the 0th index.
329         Parameters []Metadata
330 }
331
332 // CreateSubroutineType creates subroutine type debug metadata.
333 func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
334         params := d.getOrCreateTypeArray(t.Parameters)
335         result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
336         return Metadata{C: result}
337 }
338
339 // DIStructType holds the values for creating struct type debug metadata.
340 type DIStructType struct {
341         Name        string
342         File        Metadata
343         Line        int
344         SizeInBits  uint64
345         AlignInBits uint64
346         Flags       int
347         DerivedFrom Metadata
348         Elements    []Metadata
349 }
350
351 // CreateStructType creates struct type debug metadata.
352 func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
353         elements := d.getOrCreateArray(t.Elements)
354         name := C.CString(t.Name)
355         defer C.free(unsafe.Pointer(name))
356         result := C.LLVMDIBuilderCreateStructType(
357                 d.ref,
358                 scope.C,
359                 name,
360                 t.File.C,
361                 C.unsigned(t.Line),
362                 C.uint64_t(t.SizeInBits),
363                 C.uint64_t(t.AlignInBits),
364                 C.unsigned(t.Flags),
365                 t.DerivedFrom.C,
366                 elements.C,
367         )
368         return Metadata{C: result}
369 }
370
371 // DIReplaceableCompositeType holds the values for creating replaceable
372 // composite type debug metadata.
373 type DIReplaceableCompositeType struct {
374         Tag         dwarf.Tag
375         Name        string
376         File        Metadata
377         Line        int
378         RuntimeLang int
379         SizeInBits  uint64
380         AlignInBits uint64
381         Flags       int
382 }
383
384 // CreateReplaceableCompositeType creates replaceable composite type debug metadata.
385 func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
386         name := C.CString(t.Name)
387         defer C.free(unsafe.Pointer(name))
388         result := C.LLVMDIBuilderCreateReplaceableCompositeType(
389                 d.ref,
390                 C.unsigned(t.Tag),
391                 name,
392                 scope.C,
393                 t.File.C,
394                 C.unsigned(t.Line),
395                 C.unsigned(t.RuntimeLang),
396                 C.uint64_t(t.SizeInBits),
397                 C.uint64_t(t.AlignInBits),
398                 C.unsigned(t.Flags),
399         )
400         return Metadata{C: result}
401 }
402
403 // DIMemberType holds the values for creating member type debug metadata.
404 type DIMemberType struct {
405         Name         string
406         File         Metadata
407         Line         int
408         SizeInBits   uint64
409         AlignInBits  uint64
410         OffsetInBits uint64
411         Flags        int
412         Type         Metadata
413 }
414
415 // CreateMemberType creates struct type debug metadata.
416 func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
417         name := C.CString(t.Name)
418         defer C.free(unsafe.Pointer(name))
419         result := C.LLVMDIBuilderCreateMemberType(
420                 d.ref,
421                 scope.C,
422                 name,
423                 t.File.C,
424                 C.unsigned(t.Line),
425                 C.uint64_t(t.SizeInBits),
426                 C.uint64_t(t.AlignInBits),
427                 C.uint64_t(t.OffsetInBits),
428                 C.unsigned(t.Flags),
429                 t.Type.C,
430         )
431         return Metadata{C: result}
432 }
433
434 // DISubrange describes an integer value range.
435 type DISubrange struct {
436         Lo    int64
437         Count int64
438 }
439
440 // DIArrayType holds the values for creating array type debug metadata.
441 type DIArrayType struct {
442         SizeInBits  uint64
443         AlignInBits uint64
444         ElementType Metadata
445         Subscripts  []DISubrange
446 }
447
448 // CreateArrayType creates struct type debug metadata.
449 func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
450         subscriptsSlice := make([]Metadata, len(t.Subscripts))
451         for i, s := range t.Subscripts {
452                 subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
453         }
454         subscripts := d.getOrCreateArray(subscriptsSlice)
455         result := C.LLVMDIBuilderCreateArrayType(
456                 d.ref,
457                 C.uint64_t(t.SizeInBits),
458                 C.uint64_t(t.AlignInBits),
459                 t.ElementType.C,
460                 subscripts.C,
461         )
462         return Metadata{C: result}
463 }
464
465 // DITypedef holds the values for creating typedef type debug metadata.
466 type DITypedef struct {
467         Type    Metadata
468         Name    string
469         File    Metadata
470         Line    int
471         Context Metadata
472 }
473
474 // CreateTypedef creates typedef type debug metadata.
475 func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
476         name := C.CString(t.Name)
477         defer C.free(unsafe.Pointer(name))
478         result := C.LLVMDIBuilderCreateTypedef(
479                 d.ref,
480                 t.Type.C,
481                 name,
482                 t.File.C,
483                 C.unsigned(t.Line),
484                 t.Context.C,
485         )
486         return Metadata{C: result}
487 }
488
489 // getOrCreateSubrange gets a metadata node for the specified subrange,
490 // creating if required.
491 func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
492         result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
493         return Metadata{C: result}
494 }
495
496 // getOrCreateArray gets a metadata node containing the specified values,
497 // creating if required.
498 func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
499         if len(values) == 0 {
500                 return Metadata{}
501         }
502         data, length := llvmMetadataRefs(values)
503         result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
504         return Metadata{C: result}
505 }
506
507 // getOrCreateTypeArray gets a metadata node for a type array containing the
508 // specified values, creating if required.
509 func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
510         if len(values) == 0 {
511                 return Metadata{}
512         }
513         data, length := llvmMetadataRefs(values)
514         result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
515         return Metadata{C: result}
516 }
517
518 // CreateExpression creates a new descriptor for the specified
519 // variable which has a complex address expression for its address.
520 func (d *DIBuilder) CreateExpression(addr []int64) Metadata {
521         var data *C.int64_t
522         if len(addr) > 0 {
523                 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
524         }
525         result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
526         return Metadata{C: result}
527 }
528
529 // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
530 // specified basic block for the given value and associated debug metadata.
531 func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
532         result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
533         return Value{C: result}
534 }
535
536 // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
537 // specified basic block for the given value and associated debug metadata.
538 func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, offset uint64, bb BasicBlock) Value {
539         result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, C.uint64_t(offset), diVarInfo.C, expr.C, bb.C)
540         return Value{C: result}
541 }
542
543 func boolToCInt(v bool) C.int {
544         if v {
545                 return 1
546         }
547         return 0
548 }