1 //===- dibuilder.go - Bindings for DIBuilder ------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines bindings for the DIBuilder class.
12 //===----------------------------------------------------------------------===//
17 #include "DIBuilderBindings.h"
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
44 FlagPrivate = 1 << iota
63 // http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open
64 DW_LANG_Go DwarfLang = 0x0016
67 type DwarfTypeEncoding uint32
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
90 // DIBuilder is a wrapper for the LLVM DIBuilder class.
91 type DIBuilder struct {
92 ref C.LLVMDIBuilderRef
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}
102 // Destroy destroys the DIBuilder.
103 func (d *DIBuilder) Destroy() {
104 C.LLVMDIBuilderDestroy(d.ref)
107 // FInalize finalizes the debug information generated by the DIBuilder.
108 func (d *DIBuilder) Finalize() {
109 C.LLVMDIBuilderFinalize(d.ref)
112 // DICompileUnit holds the values for creating compile unit debug metadata.
113 type DICompileUnit struct {
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(
135 C.unsigned(cu.Language),
138 boolToCInt(cu.Optimized),
140 C.unsigned(cu.RuntimeVersion),
142 return Metadata{C: result}
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}
155 // DILexicalBlock holds the values for creating lexical block debug metadata.
156 type DILexicalBlock struct {
162 // CreateCompileUnit creates lexical block debug metadata.
163 func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
164 result := C.LLVMDIBuilderCreateLexicalBlock(
169 C.unsigned(b.Column),
171 return Metadata{C: result}
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}
180 // DIFunction holds the values for creating function debug metadata.
181 type DIFunction struct {
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(
208 boolToCInt(f.LocalToUnit),
209 boolToCInt(f.IsDefinition),
210 C.unsigned(f.ScopeLine),
212 boolToCInt(f.Optimized),
214 return Metadata{C: result}
217 // DIAutoVariable holds the values for creating auto variable debug metadata.
218 type DIAutoVariable struct {
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(
238 boolToCInt(v.AlwaysPreserve),
241 return Metadata{C: result}
244 // DIParameterVariable holds the values for creating parameter variable debug metadata.
245 type DIParameterVariable struct {
253 // ArgNo is the 1-based index of the argument in the function's
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(
270 boolToCInt(v.AlwaysPreserve),
273 return Metadata{C: result}
276 // DIBasicType holds the values for creating basic type debug metadata.
277 type DIBasicType struct {
281 Encoding DwarfTypeEncoding
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(
291 C.uint64_t(t.SizeInBits),
292 C.uint64_t(t.AlignInBits),
293 C.unsigned(t.Encoding),
295 return Metadata{C: result}
298 // DIPointerType holds the values for creating pointer type debug metadata.
299 type DIPointerType struct {
302 AlignInBits uint64 // optional
303 Name string // optional
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(
313 C.uint64_t(t.SizeInBits),
314 C.uint64_t(t.AlignInBits),
317 return Metadata{C: result}
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.
325 // Parameters contains the subroutine parameter types,
326 // including the return type at the 0th index.
327 Parameters []Metadata
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}
337 // DIStructType holds the values for creating struct type debug metadata.
338 type DIStructType struct {
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(
360 C.uint64_t(t.SizeInBits),
361 C.uint64_t(t.AlignInBits),
366 return Metadata{C: result}
369 // DIReplaceableCompositeType holds the values for creating replaceable
370 // composite type debug metadata.
371 type DIReplaceableCompositeType struct {
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(
393 C.unsigned(t.RuntimeLang),
394 C.uint64_t(t.SizeInBits),
395 C.uint64_t(t.AlignInBits),
398 return Metadata{C: result}
401 // DIMemberType holds the values for creating member type debug metadata.
402 type DIMemberType struct {
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(
423 C.uint64_t(t.SizeInBits),
424 C.uint64_t(t.AlignInBits),
425 C.uint64_t(t.OffsetInBits),
429 return Metadata{C: result}
432 // DISubrange describes an integer value range.
433 type DISubrange struct {
438 // DIArrayType holds the values for creating array type debug metadata.
439 type DIArrayType struct {
443 Subscripts []DISubrange
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)
452 subscripts := d.getOrCreateArray(subscriptsSlice)
453 result := C.LLVMDIBuilderCreateArrayType(
455 C.uint64_t(t.SizeInBits),
456 C.uint64_t(t.AlignInBits),
460 return Metadata{C: result}
463 // DITypedef holds the values for creating typedef type debug metadata.
464 type DITypedef struct {
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(
484 return Metadata{C: result}
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}
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 {
500 data, length := llvmMetadataRefs(values)
501 result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
502 return Metadata{C: result}
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 {
511 data, length := llvmMetadataRefs(values)
512 result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
513 return Metadata{C: result}
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 {
521 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
523 result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
524 return Metadata{C: result}
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}
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}
541 func boolToCInt(v bool) C.int {