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 // DIMemberType holds the values for creating member type debug metadata.
347 type DIMemberType struct {
358 // CreateMemberType creates struct type debug metadata.
359 func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
360 name := C.CString(t.Name)
361 defer C.free(unsafe.Pointer(name))
362 result := C.LLVMDIBuilderCreateMemberType(
368 C.uint64_t(t.SizeInBits),
369 C.uint64_t(t.AlignInBits),
370 C.uint64_t(t.OffsetInBits),
374 return Metadata{C: result}
377 // DISubrange describes an integer value range.
378 type DISubrange struct {
383 // DIArrayType holds the values for creating array type debug metadata.
384 type DIArrayType struct {
388 Subscripts []DISubrange
391 // CreateArrayType creates struct type debug metadata.
392 func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
393 subscriptsSlice := make([]Metadata, len(t.Subscripts))
394 for i, s := range t.Subscripts {
395 subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
397 subscripts := d.getOrCreateArray(subscriptsSlice)
398 result := C.LLVMDIBuilderCreateArrayType(
400 C.uint64_t(t.SizeInBits),
401 C.uint64_t(t.AlignInBits),
405 return Metadata{C: result}
408 // DITypedef holds the values for creating typedef type debug metadata.
409 type DITypedef struct {
417 // CreateTypedef creates typedef type debug metadata.
418 func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
419 name := C.CString(t.Name)
420 defer C.free(unsafe.Pointer(name))
421 result := C.LLVMDIBuilderCreateTypedef(
429 return Metadata{C: result}
432 // getOrCreateSubrange gets a metadata node for the specified subrange,
433 // creating if required.
434 func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
435 result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
436 return Metadata{C: result}
439 // getOrCreateArray gets a metadata node containing the specified values,
440 // creating if required.
441 func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
442 if len(values) == 0 {
445 data, length := llvmMetadataRefs(values)
446 result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
447 return Metadata{C: result}
450 // getOrCreateTypeArray gets a metadata node for a type array containing the
451 // specified values, creating if required.
452 func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
453 if len(values) == 0 {
456 data, length := llvmMetadataRefs(values)
457 result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
458 return Metadata{C: result}
461 // CreateExpression creates a new descriptor for the specified
462 // variable which has a complex address expression for its address.
463 func (d *DIBuilder) CreateExpression(addr []int64) Metadata {
466 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
468 result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
469 return Metadata{C: result}
472 // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
473 // specified basic block for the given value and associated debug metadata.
474 func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
475 result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
476 return Value{C: result}
479 // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
480 // specified basic block for the given value and associated debug metadata.
481 func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, offset uint64, bb BasicBlock) Value {
482 result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, C.uint64_t(offset), diVarInfo.C, expr.C, bb.C)
483 return Value{C: result}
486 func boolToCInt(v bool) C.int {