bindings/go: expose DIBuilder::createReplaceableCompositeType
[lldb.git] / llvm / 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 // DILocalVariable holds the values for creating local variable debug metadata.
220 type DILocalVariable struct {
221         Tag            dwarf.Tag
222         Name           string
223         File           Metadata
224         Line           int
225         Type           Metadata
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 Metadata, v DILocalVariable) Metadata {
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 Metadata{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) Metadata {
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 Metadata{C: result}
273 }
274
275 // DIPointerType holds the values for creating pointer type debug metadata.
276 type DIPointerType struct {
277         Pointee     Metadata
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) Metadata {
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 Metadata{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 Metadata
301
302         // Parameters contains the subroutine parameter types,
303         // including the return type at the 0th index.
304         Parameters []Metadata
305 }
306
307 // CreateSubroutineType creates subroutine type debug metadata.
308 func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
309         params := d.getOrCreateTypeArray(t.Parameters)
310         result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
311         return Metadata{C: result}
312 }
313
314 // DIStructType holds the values for creating struct type debug metadata.
315 type DIStructType struct {
316         Name        string
317         File        Metadata
318         Line        int
319         SizeInBits  uint64
320         AlignInBits uint64
321         Flags       int
322         DerivedFrom Metadata
323         Elements    []Metadata
324 }
325
326 // CreateStructType creates struct type debug metadata.
327 func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
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 Metadata{C: result}
344 }
345
346 // DIReplaceableCompositeType holds the values for creating replaceable
347 // composite type debug metadata.
348 type DIReplaceableCompositeType struct {
349         Tag         dwarf.Tag
350         Name        string
351         File        Metadata
352         Line        int
353         RuntimeLang int
354         SizeInBits  uint64
355         AlignInBits uint64
356         Flags       int
357 }
358
359 // CreateReplaceableCompositeType creates replaceable composite type debug metadata.
360 func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
361         name := C.CString(t.Name)
362         defer C.free(unsafe.Pointer(name))
363         result := C.LLVMDIBuilderCreateReplaceableCompositeType(
364                 d.ref,
365                 C.unsigned(t.Tag),
366                 name,
367                 scope.C,
368                 t.File.C,
369                 C.unsigned(t.Line),
370                 C.unsigned(t.RuntimeLang),
371                 C.uint64_t(t.SizeInBits),
372                 C.uint64_t(t.AlignInBits),
373                 C.unsigned(t.Flags),
374         )
375         return Metadata{C: result}
376 }
377
378 // DIMemberType holds the values for creating member type debug metadata.
379 type DIMemberType struct {
380         Name         string
381         File         Metadata
382         Line         int
383         SizeInBits   uint64
384         AlignInBits  uint64
385         OffsetInBits uint64
386         Flags        int
387         Type         Metadata
388 }
389
390 // CreateMemberType creates struct type debug metadata.
391 func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
392         name := C.CString(t.Name)
393         defer C.free(unsafe.Pointer(name))
394         result := C.LLVMDIBuilderCreateMemberType(
395                 d.ref,
396                 scope.C,
397                 name,
398                 t.File.C,
399                 C.unsigned(t.Line),
400                 C.uint64_t(t.SizeInBits),
401                 C.uint64_t(t.AlignInBits),
402                 C.uint64_t(t.OffsetInBits),
403                 C.unsigned(t.Flags),
404                 t.Type.C,
405         )
406         return Metadata{C: result}
407 }
408
409 // DISubrange describes an integer value range.
410 type DISubrange struct {
411         Lo    int64
412         Count int64
413 }
414
415 // DIArrayType holds the values for creating array type debug metadata.
416 type DIArrayType struct {
417         SizeInBits  uint64
418         AlignInBits uint64
419         ElementType Metadata
420         Subscripts  []DISubrange
421 }
422
423 // CreateArrayType creates struct type debug metadata.
424 func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
425         subscriptsSlice := make([]Metadata, len(t.Subscripts))
426         for i, s := range t.Subscripts {
427                 subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
428         }
429         subscripts := d.getOrCreateArray(subscriptsSlice)
430         result := C.LLVMDIBuilderCreateArrayType(
431                 d.ref,
432                 C.uint64_t(t.SizeInBits),
433                 C.uint64_t(t.AlignInBits),
434                 t.ElementType.C,
435                 subscripts.C,
436         )
437         return Metadata{C: result}
438 }
439
440 // DITypedef holds the values for creating typedef type debug metadata.
441 type DITypedef struct {
442         Type    Metadata
443         Name    string
444         File    Metadata
445         Line    int
446         Context Metadata
447 }
448
449 // CreateTypedef creates typedef type debug metadata.
450 func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
451         name := C.CString(t.Name)
452         defer C.free(unsafe.Pointer(name))
453         result := C.LLVMDIBuilderCreateTypedef(
454                 d.ref,
455                 t.Type.C,
456                 name,
457                 t.File.C,
458                 C.unsigned(t.Line),
459                 t.Context.C,
460         )
461         return Metadata{C: result}
462 }
463
464 // getOrCreateSubrange gets a metadata node for the specified subrange,
465 // creating if required.
466 func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
467         result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
468         return Metadata{C: result}
469 }
470
471 // getOrCreateArray gets a metadata node containing the specified values,
472 // creating if required.
473 func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
474         if len(values) == 0 {
475                 return Metadata{}
476         }
477         data, length := llvmMetadataRefs(values)
478         result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
479         return Metadata{C: result}
480 }
481
482 // getOrCreateTypeArray gets a metadata node for a type array containing the
483 // specified values, creating if required.
484 func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
485         if len(values) == 0 {
486                 return Metadata{}
487         }
488         data, length := llvmMetadataRefs(values)
489         result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
490         return Metadata{C: result}
491 }
492
493 // CreateExpression creates a new descriptor for the specified
494 // variable which has a complex address expression for its address.
495 func (d *DIBuilder) CreateExpression(addr []int64) Metadata {
496         var data *C.int64_t
497         if len(addr) > 0 {
498                 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
499         }
500         result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
501         return Metadata{C: result}
502 }
503
504 // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
505 // specified basic block for the given value and associated debug metadata.
506 func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
507         result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
508         return Value{C: result}
509 }
510
511 // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
512 // specified basic block for the given value and associated debug metadata.
513 func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, offset uint64, bb BasicBlock) Value {
514         result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, C.uint64_t(offset), diVarInfo.C, expr.C, bb.C)
515         return Value{C: result}
516 }
517
518 func boolToCInt(v bool) C.int {
519         if v {
520                 return 1
521         }
522         return 0
523 }