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 // DIAutoVariable holds the values for creating auto variable debug metadata.
220 type DIAutoVariable struct {
229 // CreateAutoVariable creates local variable debug metadata.
230 func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
231 name := C.CString(v.Name)
232 defer C.free(unsafe.Pointer(name))
233 result := C.LLVMDIBuilderCreateAutoVariable(
240 boolToCInt(v.AlwaysPreserve),
243 return Metadata{C: result}
246 // DIParameterVariable holds the values for creating parameter variable debug metadata.
247 type DIParameterVariable struct {
255 // ArgNo is the 1-based index of the argument in the function's
260 // CreateParameterVariable creates parameter variable debug metadata.
261 func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
262 name := C.CString(v.Name)
263 defer C.free(unsafe.Pointer(name))
264 result := C.LLVMDIBuilderCreateParameterVariable(
272 boolToCInt(v.AlwaysPreserve),
275 return Metadata{C: result}
278 // DIBasicType holds the values for creating basic type debug metadata.
279 type DIBasicType struct {
283 Encoding DwarfTypeEncoding
286 // CreateBasicType creates basic type debug metadata.
287 func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
288 name := C.CString(t.Name)
289 defer C.free(unsafe.Pointer(name))
290 result := C.LLVMDIBuilderCreateBasicType(
293 C.uint64_t(t.SizeInBits),
294 C.uint64_t(t.AlignInBits),
295 C.unsigned(t.Encoding),
297 return Metadata{C: result}
300 // DIPointerType holds the values for creating pointer type debug metadata.
301 type DIPointerType struct {
304 AlignInBits uint64 // optional
305 Name string // optional
308 // CreateBasicType creates basic type debug metadata.
309 func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
310 name := C.CString(t.Name)
311 defer C.free(unsafe.Pointer(name))
312 result := C.LLVMDIBuilderCreatePointerType(
315 C.uint64_t(t.SizeInBits),
316 C.uint64_t(t.AlignInBits),
319 return Metadata{C: result}
322 // DISubroutineType holds the values for creating subroutine type debug metadata.
323 type DISubroutineType struct {
324 // File is the file in which the subroutine type is defined.
327 // Parameters contains the subroutine parameter types,
328 // including the return type at the 0th index.
329 Parameters []Metadata
332 // CreateSubroutineType creates subroutine type debug metadata.
333 func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
334 params := d.getOrCreateTypeArray(t.Parameters)
335 result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
336 return Metadata{C: result}
339 // DIStructType holds the values for creating struct type debug metadata.
340 type DIStructType struct {
351 // CreateStructType creates struct type debug metadata.
352 func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
353 elements := d.getOrCreateArray(t.Elements)
354 name := C.CString(t.Name)
355 defer C.free(unsafe.Pointer(name))
356 result := C.LLVMDIBuilderCreateStructType(
362 C.uint64_t(t.SizeInBits),
363 C.uint64_t(t.AlignInBits),
368 return Metadata{C: result}
371 // DIReplaceableCompositeType holds the values for creating replaceable
372 // composite type debug metadata.
373 type DIReplaceableCompositeType struct {
384 // CreateReplaceableCompositeType creates replaceable composite type debug metadata.
385 func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
386 name := C.CString(t.Name)
387 defer C.free(unsafe.Pointer(name))
388 result := C.LLVMDIBuilderCreateReplaceableCompositeType(
395 C.unsigned(t.RuntimeLang),
396 C.uint64_t(t.SizeInBits),
397 C.uint64_t(t.AlignInBits),
400 return Metadata{C: result}
403 // DIMemberType holds the values for creating member type debug metadata.
404 type DIMemberType struct {
415 // CreateMemberType creates struct type debug metadata.
416 func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
417 name := C.CString(t.Name)
418 defer C.free(unsafe.Pointer(name))
419 result := C.LLVMDIBuilderCreateMemberType(
425 C.uint64_t(t.SizeInBits),
426 C.uint64_t(t.AlignInBits),
427 C.uint64_t(t.OffsetInBits),
431 return Metadata{C: result}
434 // DISubrange describes an integer value range.
435 type DISubrange struct {
440 // DIArrayType holds the values for creating array type debug metadata.
441 type DIArrayType struct {
445 Subscripts []DISubrange
448 // CreateArrayType creates struct type debug metadata.
449 func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
450 subscriptsSlice := make([]Metadata, len(t.Subscripts))
451 for i, s := range t.Subscripts {
452 subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
454 subscripts := d.getOrCreateArray(subscriptsSlice)
455 result := C.LLVMDIBuilderCreateArrayType(
457 C.uint64_t(t.SizeInBits),
458 C.uint64_t(t.AlignInBits),
462 return Metadata{C: result}
465 // DITypedef holds the values for creating typedef type debug metadata.
466 type DITypedef struct {
474 // CreateTypedef creates typedef type debug metadata.
475 func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
476 name := C.CString(t.Name)
477 defer C.free(unsafe.Pointer(name))
478 result := C.LLVMDIBuilderCreateTypedef(
486 return Metadata{C: result}
489 // getOrCreateSubrange gets a metadata node for the specified subrange,
490 // creating if required.
491 func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
492 result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
493 return Metadata{C: result}
496 // getOrCreateArray gets a metadata node containing the specified values,
497 // creating if required.
498 func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
499 if len(values) == 0 {
502 data, length := llvmMetadataRefs(values)
503 result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
504 return Metadata{C: result}
507 // getOrCreateTypeArray gets a metadata node for a type array containing the
508 // specified values, creating if required.
509 func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
510 if len(values) == 0 {
513 data, length := llvmMetadataRefs(values)
514 result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
515 return Metadata{C: result}
518 // CreateExpression creates a new descriptor for the specified
519 // variable which has a complex address expression for its address.
520 func (d *DIBuilder) CreateExpression(addr []int64) Metadata {
523 data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
525 result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
526 return Metadata{C: result}
529 // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
530 // specified basic block for the given value and associated debug metadata.
531 func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
532 result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
533 return Value{C: result}
536 // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
537 // specified basic block for the given value and associated debug metadata.
538 func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, offset uint64, bb BasicBlock) Value {
539 result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, C.uint64_t(offset), diVarInfo.C, expr.C, bb.C)
540 return Value{C: result}
543 func boolToCInt(v bool) C.int {