diff options
Diffstat (limited to 'bindings/go/llvm/dibuilder.go')
-rw-r--r-- | bindings/go/llvm/dibuilder.go | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/bindings/go/llvm/dibuilder.go b/bindings/go/llvm/dibuilder.go new file mode 100644 index 0000000..1d07e98 --- /dev/null +++ b/bindings/go/llvm/dibuilder.go @@ -0,0 +1,492 @@ +//===- dibuilder.go - Bindings for DIBuilder ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines bindings for the DIBuilder class. +// +//===----------------------------------------------------------------------===// + +package llvm + +/* +#include "DIBuilderBindings.h" +#include <stdlib.h> +*/ +import "C" + +import ( + "debug/dwarf" + "unsafe" +) + +type DwarfTag uint32 + +const ( + DW_TAG_lexical_block DwarfTag = 0x0b + DW_TAG_compile_unit DwarfTag = 0x11 + DW_TAG_variable DwarfTag = 0x34 + DW_TAG_base_type DwarfTag = 0x24 + DW_TAG_pointer_type DwarfTag = 0x0F + DW_TAG_structure_type DwarfTag = 0x13 + DW_TAG_subroutine_type DwarfTag = 0x15 + DW_TAG_file_type DwarfTag = 0x29 + DW_TAG_subprogram DwarfTag = 0x2E + DW_TAG_auto_variable DwarfTag = 0x100 + DW_TAG_arg_variable DwarfTag = 0x101 +) + +const ( + FlagPrivate = 1 << iota + FlagProtected + FlagFwdDecl + FlagAppleBlock + FlagBlockByrefStruct + FlagVirtual + FlagArtificial + FlagExplicit + FlagPrototyped + FlagObjcClassComplete + FlagObjectPointer + FlagVector + FlagStaticMember + FlagIndirectVariable +) + +type DwarfLang uint32 + +const ( + // http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open + DW_LANG_Go DwarfLang = 0x0016 +) + +type DwarfTypeEncoding uint32 + +const ( + DW_ATE_address DwarfTypeEncoding = 0x01 + DW_ATE_boolean DwarfTypeEncoding = 0x02 + DW_ATE_complex_float DwarfTypeEncoding = 0x03 + DW_ATE_float DwarfTypeEncoding = 0x04 + DW_ATE_signed DwarfTypeEncoding = 0x05 + DW_ATE_signed_char DwarfTypeEncoding = 0x06 + DW_ATE_unsigned DwarfTypeEncoding = 0x07 + DW_ATE_unsigned_char DwarfTypeEncoding = 0x08 + DW_ATE_imaginary_float DwarfTypeEncoding = 0x09 + DW_ATE_packed_decimal DwarfTypeEncoding = 0x0a + DW_ATE_numeric_string DwarfTypeEncoding = 0x0b + DW_ATE_edited DwarfTypeEncoding = 0x0c + DW_ATE_signed_fixed DwarfTypeEncoding = 0x0d + DW_ATE_unsigned_fixed DwarfTypeEncoding = 0x0e + DW_ATE_decimal_float DwarfTypeEncoding = 0x0f + DW_ATE_UTF DwarfTypeEncoding = 0x10 + DW_ATE_lo_user DwarfTypeEncoding = 0x80 + DW_ATE_hi_user DwarfTypeEncoding = 0xff +) + +// DIBuilder is a wrapper for the LLVM DIBuilder class. +type DIBuilder struct { + ref C.LLVMDIBuilderRef + m Module +} + +// NewDIBuilder creates a new DIBuilder, associated with the given module. +func NewDIBuilder(m Module) *DIBuilder { + d := C.LLVMNewDIBuilder(m.C) + return &DIBuilder{ref: d, m: m} +} + +// Destroy destroys the DIBuilder. +func (d *DIBuilder) Destroy() { + C.LLVMDIBuilderDestroy(d.ref) +} + +// FInalize finalizes the debug information generated by the DIBuilder. +func (d *DIBuilder) Finalize() { + C.LLVMDIBuilderFinalize(d.ref) +} + +// DICompileUnit holds the values for creating compile unit debug metadata. +type DICompileUnit struct { + Language DwarfLang + File string + Dir string + Producer string + Optimized bool + Flags string + RuntimeVersion int +} + +// CreateCompileUnit creates compile unit debug metadata. +func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Value { + file := C.CString(cu.File) + defer C.free(unsafe.Pointer(file)) + dir := C.CString(cu.Dir) + defer C.free(unsafe.Pointer(dir)) + producer := C.CString(cu.Producer) + defer C.free(unsafe.Pointer(producer)) + flags := C.CString(cu.Flags) + defer C.free(unsafe.Pointer(flags)) + result := C.LLVMDIBuilderCreateCompileUnit( + d.ref, + C.unsigned(cu.Language), + file, dir, + producer, + boolToCInt(cu.Optimized), + flags, + C.unsigned(cu.RuntimeVersion), + ) + return Value{C: result} +} + +// CreateCompileUnit creates file debug metadata. +func (d *DIBuilder) CreateFile(filename, dir string) Value { + cfilename := C.CString(filename) + defer C.free(unsafe.Pointer(cfilename)) + cdir := C.CString(dir) + defer C.free(unsafe.Pointer(cdir)) + result := C.LLVMDIBuilderCreateFile(d.ref, cfilename, cdir) + return Value{C: result} +} + +// DILexicalBlock holds the values for creating lexical block debug metadata. +type DILexicalBlock struct { + File Value + Line int + Column int +} + +// CreateCompileUnit creates lexical block debug metadata. +func (d *DIBuilder) CreateLexicalBlock(diScope Value, b DILexicalBlock) Value { + result := C.LLVMDIBuilderCreateLexicalBlock( + d.ref, + diScope.C, + b.File.C, + C.unsigned(b.Line), + C.unsigned(b.Column), + ) + return Value{C: result} +} + +func (d *DIBuilder) CreateLexicalBlockFile(diScope Value, diFile Value, discriminator int) Value { + result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C, + C.unsigned(discriminator)) + return Value{C: result} +} + +// DIFunction holds the values for creating function debug metadata. +type DIFunction struct { + Name string + LinkageName string + File Value + Line int + Type Value + LocalToUnit bool + IsDefinition bool + ScopeLine int + Flags int + Optimized bool + Function Value +} + +// CreateCompileUnit creates function debug metadata. +func (d *DIBuilder) CreateFunction(diScope Value, f DIFunction) Value { + name := C.CString(f.Name) + defer C.free(unsafe.Pointer(name)) + linkageName := C.CString(f.LinkageName) + defer C.free(unsafe.Pointer(linkageName)) + result := C.LLVMDIBuilderCreateFunction( + d.ref, + diScope.C, + name, + linkageName, + f.File.C, + C.unsigned(f.Line), + f.Type.C, + boolToCInt(f.LocalToUnit), + boolToCInt(f.IsDefinition), + C.unsigned(f.ScopeLine), + C.unsigned(f.Flags), + boolToCInt(f.Optimized), + f.Function.C, + ) + return Value{C: result} +} + +// DILocalVariable holds the values for creating local variable debug metadata. +type DILocalVariable struct { + Tag dwarf.Tag + Name string + File Value + Line int + Type Value + AlwaysPreserve bool + Flags int + + // ArgNo is the 1-based index of the argument in the function's + // parameter list if it is an argument, or 0 otherwise. + ArgNo int +} + +// CreateLocalVariable creates local variable debug metadata. +func (d *DIBuilder) CreateLocalVariable(scope Value, v DILocalVariable) Value { + name := C.CString(v.Name) + defer C.free(unsafe.Pointer(name)) + result := C.LLVMDIBuilderCreateLocalVariable( + d.ref, + C.unsigned(v.Tag), + scope.C, + name, + v.File.C, + C.unsigned(v.Line), + v.Type.C, + boolToCInt(v.AlwaysPreserve), + C.unsigned(v.Flags), + C.unsigned(v.ArgNo), + ) + return Value{C: result} +} + +// DIBasicType holds the values for creating basic type debug metadata. +type DIBasicType struct { + Name string + SizeInBits uint64 + AlignInBits uint64 + Encoding DwarfTypeEncoding +} + +// CreateBasicType creates basic type debug metadata. +func (d *DIBuilder) CreateBasicType(t DIBasicType) Value { + name := C.CString(t.Name) + defer C.free(unsafe.Pointer(name)) + result := C.LLVMDIBuilderCreateBasicType( + d.ref, + name, + C.uint64_t(t.SizeInBits), + C.uint64_t(t.AlignInBits), + C.unsigned(t.Encoding), + ) + return Value{C: result} +} + +// DIPointerType holds the values for creating pointer type debug metadata. +type DIPointerType struct { + Pointee Value + SizeInBits uint64 + AlignInBits uint64 // optional + Name string // optional +} + +// CreateBasicType creates basic type debug metadata. +func (d *DIBuilder) CreatePointerType(t DIPointerType) Value { + name := C.CString(t.Name) + defer C.free(unsafe.Pointer(name)) + result := C.LLVMDIBuilderCreatePointerType( + d.ref, + t.Pointee.C, + C.uint64_t(t.SizeInBits), + C.uint64_t(t.AlignInBits), + name, + ) + return Value{C: result} +} + +// DISubroutineType holds the values for creating subroutine type debug metadata. +type DISubroutineType struct { + // File is the file in which the subroutine type is defined. + File Value + + // Parameters contains the subroutine parameter types, + // including the return type at the 0th index. + Parameters []Value +} + +// CreateSubroutineType creates subroutine type debug metadata. +func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Value { + params := d.getOrCreateTypeArray(t.Parameters) + result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C) + return Value{C: result} +} + +// DIStructType holds the values for creating struct type debug metadata. +type DIStructType struct { + Name string + File Value + Line int + SizeInBits uint64 + AlignInBits uint64 + Flags int + DerivedFrom Value + Elements []Value +} + +// CreateStructType creates struct type debug metadata. +func (d *DIBuilder) CreateStructType(scope Value, t DIStructType) Value { + elements := d.getOrCreateArray(t.Elements) + name := C.CString(t.Name) + defer C.free(unsafe.Pointer(name)) + result := C.LLVMDIBuilderCreateStructType( + d.ref, + scope.C, + name, + t.File.C, + C.unsigned(t.Line), + C.uint64_t(t.SizeInBits), + C.uint64_t(t.AlignInBits), + C.unsigned(t.Flags), + t.DerivedFrom.C, + elements.C, + ) + return Value{C: result} +} + +// DIMemberType holds the values for creating member type debug metadata. +type DIMemberType struct { + Name string + File Value + Line int + SizeInBits uint64 + AlignInBits uint64 + OffsetInBits uint64 + Flags int + Type Value +} + +// CreateMemberType creates struct type debug metadata. +func (d *DIBuilder) CreateMemberType(scope Value, t DIMemberType) Value { + name := C.CString(t.Name) + defer C.free(unsafe.Pointer(name)) + result := C.LLVMDIBuilderCreateMemberType( + d.ref, + scope.C, + name, + t.File.C, + C.unsigned(t.Line), + C.uint64_t(t.SizeInBits), + C.uint64_t(t.AlignInBits), + C.uint64_t(t.OffsetInBits), + C.unsigned(t.Flags), + t.Type.C, + ) + return Value{C: result} +} + +// DISubrange describes an integer value range. +type DISubrange struct { + Lo int64 + Count int64 +} + +// DIArrayType holds the values for creating array type debug metadata. +type DIArrayType struct { + SizeInBits uint64 + AlignInBits uint64 + ElementType Value + Subscripts []DISubrange +} + +// CreateArrayType creates struct type debug metadata. +func (d *DIBuilder) CreateArrayType(t DIArrayType) Value { + subscriptsSlice := make([]Value, len(t.Subscripts)) + for i, s := range t.Subscripts { + subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count) + } + subscripts := d.getOrCreateArray(subscriptsSlice) + result := C.LLVMDIBuilderCreateArrayType( + d.ref, + C.uint64_t(t.SizeInBits), + C.uint64_t(t.AlignInBits), + t.ElementType.C, + subscripts.C, + ) + return Value{C: result} +} + +// DITypedef holds the values for creating typedef type debug metadata. +type DITypedef struct { + Type Value + Name string + File Value + Line int + Context Value +} + +// CreateTypedef creates typedef type debug metadata. +func (d *DIBuilder) CreateTypedef(t DITypedef) Value { + name := C.CString(t.Name) + defer C.free(unsafe.Pointer(name)) + result := C.LLVMDIBuilderCreateTypedef( + d.ref, + t.Type.C, + name, + t.File.C, + C.unsigned(t.Line), + t.Context.C, + ) + return Value{C: result} +} + +// getOrCreateSubrange gets a metadata node for the specified subrange, +// creating if required. +func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Value { + result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count)) + return Value{C: result} +} + +// getOrCreateArray gets a metadata node containing the specified values, +// creating if required. +func (d *DIBuilder) getOrCreateArray(values []Value) Value { + if len(values) == 0 { + return Value{} + } + var data *C.LLVMValueRef + length := len(values) + if length > 0 { + data = &values[0].C + } + result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length)) + return Value{C: result} +} + +// getOrCreateTypeArray gets a metadata node for a type array containing the +// specified values, creating if required. +func (d *DIBuilder) getOrCreateTypeArray(values []Value) Value { + if len(values) == 0 { + return Value{} + } + var data *C.LLVMValueRef + length := len(values) + if length > 0 { + data = &values[0].C + } + result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length)) + return Value{C: result} +} + +// CreateExpression creates a new descriptor for the specified +// variable which has a complex address expression for its address. +func (d *DIBuilder) CreateExpression(addr []int64) Value { + var data *C.int64_t + if len(addr) > 0 { + data = (*C.int64_t)(unsafe.Pointer(&addr[0])) + } + result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr))) + return Value{C: result} +} + +// InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the +// specified basic block for the given value and associated debug metadata. +func (d *DIBuilder) InsertDeclareAtEnd(v, diVarInfo, expr Value, bb BasicBlock) Value { + result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C) + return Value{C: result} +} + +func boolToCInt(v bool) C.int { + if v { + return 1 + } + return 0 +} |