Add C API bindings for DIBuilder 'Type' APIs
[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.LLVMCreateDIBuilder(m.C)
99         return &DIBuilder{ref: d, m: m}
100 }
101
102 // Destroy destroys the DIBuilder.
103 func (d *DIBuilder) Destroy() {
104         C.LLVMDisposeDIBuilder(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.LLVMDWARFSourceLanguage(cu.Language),
136                 C.LLVMDIBuilderCreateFile(d.ref, file, C.size_t(len(cu.File)), dir, C.size_t(len(cu.Dir))),
137                 producer, C.size_t(len(cu.Producer)),
138                 C.LLVMBool(boolToCInt(cu.Optimized)),
139                 flags, C.size_t(len(cu.Flags)),
140                 C.unsigned(cu.RuntimeVersion),
141                 /*SplitName=*/ nil, 0,
142                 C.LLVMDWARFEmissionFull,
143                 /*DWOId=*/ 0,
144                 /*SplitDebugInlining*/ C.LLVMBool(boolToCInt(true)),
145                 /*DebugInfoForProfiling*/ C.LLVMBool(boolToCInt(false)),
146         )
147         return Metadata{C: result}
148 }
149
150 // CreateFile creates file debug metadata.
151 func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
152         cfilename := C.CString(filename)
153         defer C.free(unsafe.Pointer(cfilename))
154         cdir := C.CString(dir)
155         defer C.free(unsafe.Pointer(cdir))
156         result := C.LLVMDIBuilderCreateFile(d.ref,
157                 cfilename, C.size_t(len(filename)),
158                 cdir, C.size_t(len(dir)))
159         return Metadata{C: result}
160 }
161
162 // DILexicalBlock holds the values for creating lexical block debug metadata.
163 type DILexicalBlock struct {
164         File   Metadata
165         Line   int
166         Column int
167 }
168
169 // CreateLexicalBlock creates lexical block debug metadata.
170 func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
171         result := C.LLVMDIBuilderCreateLexicalBlock(
172                 d.ref,
173                 diScope.C,
174                 b.File.C,
175                 C.unsigned(b.Line),
176                 C.unsigned(b.Column),
177         )
178         return Metadata{C: result}
179 }
180
181 func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata {
182         result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
183                 C.unsigned(discriminator))
184         return Metadata{C: result}
185 }
186
187 // DIFunction holds the values for creating function debug metadata.
188 type DIFunction struct {
189         Name         string
190         LinkageName  string
191         File         Metadata
192         Line         int
193         Type         Metadata
194         LocalToUnit  bool
195         IsDefinition bool
196         ScopeLine    int
197         Flags        int
198         Optimized    bool
199 }
200
201 // CreateFunction creates function debug metadata.
202 func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata {
203         name := C.CString(f.Name)
204         defer C.free(unsafe.Pointer(name))
205         linkageName := C.CString(f.LinkageName)
206         defer C.free(unsafe.Pointer(linkageName))
207         result := C.LLVMDIBuilderCreateFunction(
208                 d.ref,
209                 diScope.C,
210                 name,
211                 linkageName,
212                 f.File.C,
213                 C.unsigned(f.Line),
214                 f.Type.C,
215                 boolToCInt(f.LocalToUnit),
216                 boolToCInt(f.IsDefinition),
217                 C.unsigned(f.ScopeLine),
218                 C.unsigned(f.Flags),
219                 boolToCInt(f.Optimized),
220         )
221         return Metadata{C: result}
222 }
223
224 // DIAutoVariable holds the values for creating auto variable debug metadata.
225 type DIAutoVariable struct {
226         Name           string
227         File           Metadata
228         Line           int
229         Type           Metadata
230         AlwaysPreserve bool
231         Flags          int
232         AlignInBits    uint32
233 }
234
235 // CreateAutoVariable creates local variable debug metadata.
236 func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
237         name := C.CString(v.Name)
238         defer C.free(unsafe.Pointer(name))
239         result := C.LLVMDIBuilderCreateAutoVariable(
240                 d.ref,
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.uint32_t(v.AlignInBits),
249         )
250         return Metadata{C: result}
251 }
252
253 // DIParameterVariable holds the values for creating parameter variable debug metadata.
254 type DIParameterVariable struct {
255         Name           string
256         File           Metadata
257         Line           int
258         Type           Metadata
259         AlwaysPreserve bool
260         Flags          int
261
262         // ArgNo is the 1-based index of the argument in the function's
263         // parameter list.
264         ArgNo int
265 }
266
267 // CreateParameterVariable creates parameter variable debug metadata.
268 func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
269         name := C.CString(v.Name)
270         defer C.free(unsafe.Pointer(name))
271         result := C.LLVMDIBuilderCreateParameterVariable(
272                 d.ref,
273                 scope.C,
274                 name,
275                 C.unsigned(v.ArgNo),
276                 v.File.C,
277                 C.unsigned(v.Line),
278                 v.Type.C,
279                 boolToCInt(v.AlwaysPreserve),
280                 C.unsigned(v.Flags),
281         )
282         return Metadata{C: result}
283 }
284
285 // DIBasicType holds the values for creating basic type debug metadata.
286 type DIBasicType struct {
287         Name       string
288         SizeInBits uint64
289         Encoding   DwarfTypeEncoding
290 }
291
292 // CreateBasicType creates basic type debug metadata.
293 func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
294         name := C.CString(t.Name)
295         defer C.free(unsafe.Pointer(name))
296         result := C.LLVMDIBuilderCreateBasicType(
297                 d.ref,
298                 name,
299                 C.size_t(len(t.Name)),
300                 C.unsigned(t.SizeInBits),
301                 C.unsigned(t.Encoding),
302         )
303         return Metadata{C: result}
304 }
305
306 // DIPointerType holds the values for creating pointer type debug metadata.
307 type DIPointerType struct {
308         Pointee     Metadata
309         SizeInBits  uint64
310         AlignInBits uint32 // optional
311         AddressSpace uint32
312         Name        string // optional
313 }
314
315 // CreatePointerType creates a type that represents a pointer to another type.
316 func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
317         name := C.CString(t.Name)
318         defer C.free(unsafe.Pointer(name))
319         result := C.LLVMDIBuilderCreatePointerType(
320                 d.ref,
321                 t.Pointee.C,
322                 C.unsigned(t.SizeInBits),
323                 C.unsigned(t.AlignInBits),
324                 C.unsigned(t.AddressSpace),
325                 name,
326                 C.size_t(len(t.Name)),
327         )
328         return Metadata{C: result}
329 }
330
331 // DISubroutineType holds the values for creating subroutine type debug metadata.
332 type DISubroutineType struct {
333         // File is the file in which the subroutine type is defined.
334         File Metadata
335
336         // Parameters contains the subroutine parameter types,
337         // including the return type at the 0th index.
338         Parameters []Metadata
339
340         Flags int
341 }
342
343 // CreateSubroutineType creates subroutine type debug metadata.
344 func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
345         params, length := llvmMetadataRefs(t.Parameters)
346         result := C.LLVMDIBuilderCreateSubroutineType(
347                 d.ref,
348                 t.File.C,
349                 params,
350                 length,
351                 C.LLVMDIFlags(t.Flags),
352         )
353         return Metadata{C: result}
354 }
355
356 // DIStructType holds the values for creating struct type debug metadata.
357 type DIStructType struct {
358         Name        string
359         File        Metadata
360         Line        int
361         SizeInBits  uint64
362         AlignInBits uint32
363         Flags       int
364         DerivedFrom Metadata
365         Elements    []Metadata
366         VTableHolder Metadata // optional
367         UniqueID     string
368 }
369
370 // CreateStructType creates struct type debug metadata.
371 func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
372         elements, length := llvmMetadataRefs(t.Elements)
373         name := C.CString(t.Name)
374         uniqueID := C.CString(t.UniqueID)
375         defer C.free(unsafe.Pointer(name))
376         defer C.free(unsafe.Pointer(uniqueID))
377         result := C.LLVMDIBuilderCreateStructType(
378                 d.ref,
379                 scope.C,
380                 name,
381                 C.size_t(len(t.Name)),
382                 t.File.C,
383                 C.unsigned(t.Line),
384                 C.unsigned(t.SizeInBits),
385                 C.unsigned(t.AlignInBits),
386                 C.LLVMDIFlags(t.Flags),
387                 t.DerivedFrom.C,
388                 elements,
389                 length,
390                 C.unsigned(0), // Optional Objective-C runtime version.
391                 t.VTableHolder.C,
392                 uniqueID,
393                 C.uint64_t(len(t.UniqueID)),
394         )
395         return Metadata{C: result}
396 }
397
398 // DIReplaceableCompositeType holds the values for creating replaceable
399 // composite type debug metadata.
400 type DIReplaceableCompositeType struct {
401         Tag         dwarf.Tag
402         Name        string
403         File        Metadata
404         Line        int
405         RuntimeLang int
406         SizeInBits  uint64
407         AlignInBits uint32
408         Flags       int
409         UniqueID    string
410 }
411
412 // CreateReplaceableCompositeType creates replaceable composite type debug metadata.
413 func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
414         name := C.CString(t.Name)
415         uniqueID := C.CString(t.UniqueID)
416         defer C.free(unsafe.Pointer(name))
417         defer C.free(unsafe.Pointer(uniqueID))
418         result := C.LLVMDIBuilderCreateReplaceableCompositeType(
419                 d.ref,
420                 C.unsigned(t.Tag),
421                 name,
422                 C.size_t(len(t.Name)),
423                 scope.C,
424                 t.File.C,
425                 C.unsigned(t.Line),
426                 C.unsigned(t.RuntimeLang),
427                 C.unsigned(t.SizeInBits),
428                 C.unsigned(t.AlignInBits),
429                 C.LLVMDIFlags(t.Flags),
430                 uniqueID,
431                 C.size_t(len(t.UniqueID)),
432         )
433         return Metadata{C: result}
434 }
435
436 // DIMemberType holds the values for creating member type debug metadata.
437 type DIMemberType struct {
438         Name         string
439         File         Metadata
440         Line         int
441         SizeInBits   uint64
442         AlignInBits  uint32
443         OffsetInBits uint64
444         Flags        int
445         Type         Metadata
446 }
447
448 // CreateMemberType creates struct type debug metadata.
449 func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
450         name := C.CString(t.Name)
451         defer C.free(unsafe.Pointer(name))
452         result := C.LLVMDIBuilderCreateMemberType(
453                 d.ref,
454                 scope.C,
455                 name,
456                 C.size_t(len(t.Name)),
457                 t.File.C,
458                 C.unsigned(t.Line),
459                 C.unsigned(t.SizeInBits),
460                 C.unsigned(t.AlignInBits),
461                 C.unsigned(t.OffsetInBits),
462                 C.LLVMDIFlags(t.Flags),
463                 t.Type.C,
464         )
465         return Metadata{C: result}
466 }
467
468 // DISubrange describes an integer value range.
469 type DISubrange struct {
470         Lo    int64
471         Count int64
472 }
473
474 // DIArrayType holds the values for creating array type debug metadata.
475 type DIArrayType struct {
476         SizeInBits  uint64
477         AlignInBits uint32
478         ElementType Metadata
479         Subscripts  []DISubrange
480 }
481
482 // CreateArrayType creates struct type debug metadata.
483 func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
484         subscriptsSlice := make([]Metadata, len(t.Subscripts))
485         for i, s := range t.Subscripts {
486                 subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
487         }
488         subscripts, length := llvmMetadataRefs(subscriptsSlice)
489         result := C.LLVMDIBuilderCreateArrayType(
490                 d.ref,
491                 C.unsigned(t.SizeInBits),
492                 C.unsigned(t.AlignInBits),
493                 t.ElementType.C,
494                 subscripts,
495                 length,
496         )
497         return Metadata{C: result}
498 }
499
500 // DITypedef holds the values for creating typedef type debug metadata.
501 type DITypedef struct {
502         Type    Metadata
503         Name    string
504         File    Metadata
505         Line    int
506         Context Metadata
507 }
508
509 // CreateTypedef creates typedef type debug metadata.
510 func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
511         name := C.CString(t.Name)
512         defer C.free(unsafe.Pointer(name))
513         result := C.LLVMDIBuilderCreateTypedef(
514                 d.ref,
515                 t.Type.C,
516                 name,
517                 t.File.C,
518                 C.unsigned(t.Line),
519                 t.Context.C,
520         )
521         return Metadata{C: result}
522 }
523
524 // getOrCreateSubrange gets a metadata node for the specified subrange,
525 // creating if required.
526 func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
527         result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
528         return Metadata{C: result}
529 }
530
531 // getOrCreateArray gets a metadata node containing the specified values,
532 // creating if required.
533 func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
534         if len(values) == 0 {
535                 return Metadata{}
536         }
537         data, length := llvmMetadataRefs(values)
538         result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
539         return Metadata{C: result}
540 }
541
542 // getOrCreateTypeArray gets a metadata node for a type array containing the
543 // specified values, creating if required.
544 func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
545         if len(values) == 0 {
546                 return Metadata{}
547         }
548         data, length := llvmMetadataRefs(values)
549         result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
550         return Metadata{C: result}
551 }
552
553 // CreateExpression creates a new descriptor for the specified
554 // variable which has a complex address expression for its address.
555 func (d *DIBuilder) CreateExpression(addr []int64) Metadata {
556         var data *C.int64_t
557         if len(addr) > 0 {
558                 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
559         }
560         result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
561         return Metadata{C: result}
562 }
563
564 // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
565 // specified basic block for the given value and associated debug metadata.
566 func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
567         result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
568         return Value{C: result}
569 }
570
571 // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
572 // specified basic block for the given value and associated debug metadata.
573 func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
574         result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
575         return Value{C: result}
576 }
577
578 func boolToCInt(v bool) C.int {
579         if v {
580                 return 1
581         }
582         return 0
583 }