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