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 {
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(
209 boolToCInt(f.LocalToUnit),
210 boolToCInt(f.IsDefinition),
211 C.unsigned(f.ScopeLine),
213 boolToCInt(f.Optimized),
216 return Metadata{C: result}
219 // DILocalVariable holds the values for creating local variable debug metadata.
220 type DILocalVariable struct {
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.
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(
246 boolToCInt(v.AlwaysPreserve),
250 return Metadata{C: result}
253 // DIBasicType holds the values for creating basic type debug metadata.
254 type DIBasicType struct {
258 Encoding DwarfTypeEncoding
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(
268 C.uint64_t(t.SizeInBits),
269 C.uint64_t(t.AlignInBits),
270 C.unsigned(t.Encoding),
272 return Metadata{C: result}
275 // DIPointerType holds the values for creating pointer type debug metadata.
276 type DIPointerType struct {
279 AlignInBits uint64 // optional
280 Name string // optional
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(
290 C.uint64_t(t.SizeInBits),
291 C.uint64_t(t.AlignInBits),
294 return Metadata{C: result}
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.
302 // Parameters contains the subroutine parameter types,
303 // including the return type at the 0th index.
304 Parameters []Metadata
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}
314 // DIStructType holds the values for creating struct type debug metadata.
315 type DIStructType struct {
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(
337 C.uint64_t(t.SizeInBits),
338 C.uint64_t(t.AlignInBits),
343 return Metadata{C: result}
346 // DIReplaceableCompositeType holds the values for creating replaceable
347 // composite type debug metadata.
348 type DIReplaceableCompositeType struct {
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(
370 C.unsigned(t.RuntimeLang),
371 C.uint64_t(t.SizeInBits),
372 C.uint64_t(t.AlignInBits),
375 return Metadata{C: result}
378 // DIMemberType holds the values for creating member type debug metadata.
379 type DIMemberType struct {
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(
400 C.uint64_t(t.SizeInBits),
401 C.uint64_t(t.AlignInBits),
402 C.uint64_t(t.OffsetInBits),
406 return Metadata{C: result}
409 // DISubrange describes an integer value range.
410 type DISubrange struct {
415 // DIArrayType holds the values for creating array type debug metadata.
416 type DIArrayType struct {
420 Subscripts []DISubrange
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)
429 subscripts := d.getOrCreateArray(subscriptsSlice)
430 result := C.LLVMDIBuilderCreateArrayType(
432 C.uint64_t(t.SizeInBits),
433 C.uint64_t(t.AlignInBits),
437 return Metadata{C: result}
440 // DITypedef holds the values for creating typedef type debug metadata.
441 type DITypedef struct {
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(
461 return Metadata{C: result}
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}
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 {
477 data, length := llvmMetadataRefs(values)
478 result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
479 return Metadata{C: result}
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 {
488 data, length := llvmMetadataRefs(values)
489 result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
490 return Metadata{C: result}
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 {
498 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
500 result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
501 return Metadata{C: result}
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}
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}
518 func boolToCInt(v bool) C.int {