Initial version of Go bindings.
[oota-llvm.git] / bindings / go / llvm / dibuilder.go
diff --git a/bindings/go/llvm/dibuilder.go b/bindings/go/llvm/dibuilder.go
new file mode 100644 (file)
index 0000000..1d07e98
--- /dev/null
@@ -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
+}