1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00
llvm-mirror/bindings/go/llvm/dibuilder.go
Chandler Carruth ae65e281f3 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00

607 lines
16 KiB
Go

//===- dibuilder.go - Bindings for DIBuilder ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the DIBuilder class.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "IRBindings.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.LLVMCreateDIBuilder(m.C)
return &DIBuilder{ref: d, m: m}
}
// Destroy destroys the DIBuilder.
func (d *DIBuilder) Destroy() {
C.LLVMDisposeDIBuilder(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) Metadata {
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.LLVMDWARFSourceLanguage(cu.Language),
C.LLVMDIBuilderCreateFile(d.ref, file, C.size_t(len(cu.File)), dir, C.size_t(len(cu.Dir))),
producer, C.size_t(len(cu.Producer)),
C.LLVMBool(boolToCInt(cu.Optimized)),
flags, C.size_t(len(cu.Flags)),
C.unsigned(cu.RuntimeVersion),
/*SplitName=*/ nil, 0,
C.LLVMDWARFEmissionFull,
/*DWOId=*/ 0,
/*SplitDebugInlining*/ C.LLVMBool(boolToCInt(true)),
/*DebugInfoForProfiling*/ C.LLVMBool(boolToCInt(false)),
)
return Metadata{C: result}
}
// CreateFile creates file debug metadata.
func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
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, C.size_t(len(filename)),
cdir, C.size_t(len(dir)))
return Metadata{C: result}
}
// DILexicalBlock holds the values for creating lexical block debug metadata.
type DILexicalBlock struct {
File Metadata
Line int
Column int
}
// CreateLexicalBlock creates lexical block debug metadata.
func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
result := C.LLVMDIBuilderCreateLexicalBlock(
d.ref,
diScope.C,
b.File.C,
C.unsigned(b.Line),
C.unsigned(b.Column),
)
return Metadata{C: result}
}
func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata {
result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
C.unsigned(discriminator))
return Metadata{C: result}
}
// DIFunction holds the values for creating function debug metadata.
type DIFunction struct {
Name string
LinkageName string
File Metadata
Line int
Type Metadata
LocalToUnit bool
IsDefinition bool
ScopeLine int
Flags int
Optimized bool
}
// CreateFunction creates function debug metadata.
func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata {
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, C.size_t(len(f.Name)),
linkageName, C.size_t(len(f.LinkageName)),
f.File.C,
C.unsigned(f.Line),
f.Type.C,
C.LLVMBool(boolToCInt(f.LocalToUnit)),
C.LLVMBool(boolToCInt(f.IsDefinition)),
C.unsigned(f.ScopeLine),
C.LLVMDIFlags(f.Flags),
C.LLVMBool(boolToCInt(f.Optimized)),
)
return Metadata{C: result}
}
// DIAutoVariable holds the values for creating auto variable debug metadata.
type DIAutoVariable struct {
Name string
File Metadata
Line int
Type Metadata
AlwaysPreserve bool
Flags int
AlignInBits uint32
}
// CreateAutoVariable creates local variable debug metadata.
func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
name := C.CString(v.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateAutoVariable(
d.ref,
scope.C,
name, C.size_t(len(v.Name)),
v.File.C,
C.unsigned(v.Line),
v.Type.C,
C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
C.LLVMDIFlags(v.Flags),
C.uint32_t(v.AlignInBits),
)
return Metadata{C: result}
}
// DIParameterVariable holds the values for creating parameter variable debug metadata.
type DIParameterVariable struct {
Name string
File Metadata
Line int
Type Metadata
AlwaysPreserve bool
Flags int
// ArgNo is the 1-based index of the argument in the function's
// parameter list.
ArgNo int
}
// CreateParameterVariable creates parameter variable debug metadata.
func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
name := C.CString(v.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateParameterVariable(
d.ref,
scope.C,
name, C.size_t(len(v.Name)),
C.unsigned(v.ArgNo),
v.File.C,
C.unsigned(v.Line),
v.Type.C,
C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
C.LLVMDIFlags(v.Flags),
)
return Metadata{C: result}
}
// DIBasicType holds the values for creating basic type debug metadata.
type DIBasicType struct {
Name string
SizeInBits uint64
Encoding DwarfTypeEncoding
}
// CreateBasicType creates basic type debug metadata.
func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
name := C.CString(t.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateBasicType(
d.ref,
name,
C.size_t(len(t.Name)),
C.uint64_t(t.SizeInBits),
C.LLVMDWARFTypeEncoding(t.Encoding),
C.LLVMDIFlags(0),
)
return Metadata{C: result}
}
// DIPointerType holds the values for creating pointer type debug metadata.
type DIPointerType struct {
Pointee Metadata
SizeInBits uint64
AlignInBits uint32 // optional
AddressSpace uint32
Name string // optional
}
// CreatePointerType creates a type that represents a pointer to another type.
func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
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.uint32_t(t.AlignInBits),
C.unsigned(t.AddressSpace),
name,
C.size_t(len(t.Name)),
)
return Metadata{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 Metadata
// Parameters contains the subroutine parameter types,
// including the return type at the 0th index.
Parameters []Metadata
Flags int
}
// CreateSubroutineType creates subroutine type debug metadata.
func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
params, length := llvmMetadataRefs(t.Parameters)
result := C.LLVMDIBuilderCreateSubroutineType(
d.ref,
t.File.C,
params,
length,
C.LLVMDIFlags(t.Flags),
)
return Metadata{C: result}
}
// DIStructType holds the values for creating struct type debug metadata.
type DIStructType struct {
Name string
File Metadata
Line int
SizeInBits uint64
AlignInBits uint32
Flags int
DerivedFrom Metadata
Elements []Metadata
VTableHolder Metadata // optional
UniqueID string
}
// CreateStructType creates struct type debug metadata.
func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
elements, length := llvmMetadataRefs(t.Elements)
name := C.CString(t.Name)
uniqueID := C.CString(t.UniqueID)
defer C.free(unsafe.Pointer(name))
defer C.free(unsafe.Pointer(uniqueID))
result := C.LLVMDIBuilderCreateStructType(
d.ref,
scope.C,
name,
C.size_t(len(t.Name)),
t.File.C,
C.unsigned(t.Line),
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
C.LLVMDIFlags(t.Flags),
t.DerivedFrom.C,
elements,
length,
C.unsigned(0), // Optional Objective-C runtime version.
t.VTableHolder.C,
uniqueID,
C.size_t(len(t.UniqueID)),
)
return Metadata{C: result}
}
// DIReplaceableCompositeType holds the values for creating replaceable
// composite type debug metadata.
type DIReplaceableCompositeType struct {
Tag dwarf.Tag
Name string
File Metadata
Line int
RuntimeLang int
SizeInBits uint64
AlignInBits uint32
Flags int
UniqueID string
}
// CreateReplaceableCompositeType creates replaceable composite type debug metadata.
func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
name := C.CString(t.Name)
uniqueID := C.CString(t.UniqueID)
defer C.free(unsafe.Pointer(name))
defer C.free(unsafe.Pointer(uniqueID))
result := C.LLVMDIBuilderCreateReplaceableCompositeType(
d.ref,
C.unsigned(t.Tag),
name,
C.size_t(len(t.Name)),
scope.C,
t.File.C,
C.unsigned(t.Line),
C.unsigned(t.RuntimeLang),
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
C.LLVMDIFlags(t.Flags),
uniqueID,
C.size_t(len(t.UniqueID)),
)
return Metadata{C: result}
}
// DIMemberType holds the values for creating member type debug metadata.
type DIMemberType struct {
Name string
File Metadata
Line int
SizeInBits uint64
AlignInBits uint32
OffsetInBits uint64
Flags int
Type Metadata
}
// CreateMemberType creates struct type debug metadata.
func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
name := C.CString(t.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateMemberType(
d.ref,
scope.C,
name,
C.size_t(len(t.Name)),
t.File.C,
C.unsigned(t.Line),
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
C.uint64_t(t.OffsetInBits),
C.LLVMDIFlags(t.Flags),
t.Type.C,
)
return Metadata{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 uint32
ElementType Metadata
Subscripts []DISubrange
}
// CreateArrayType creates struct type debug metadata.
func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
subscriptsSlice := make([]Metadata, len(t.Subscripts))
for i, s := range t.Subscripts {
subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
}
subscripts, length := llvmMetadataRefs(subscriptsSlice)
result := C.LLVMDIBuilderCreateArrayType(
d.ref,
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
t.ElementType.C,
subscripts,
length,
)
return Metadata{C: result}
}
// DITypedef holds the values for creating typedef type debug metadata.
type DITypedef struct {
Type Metadata
Name string
File Metadata
Line int
Context Metadata
}
// CreateTypedef creates typedef type debug metadata.
func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
name := C.CString(t.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateTypedef(
d.ref,
t.Type.C,
name,
C.size_t(len(t.Name)),
t.File.C,
C.unsigned(t.Line),
t.Context.C,
)
return Metadata{C: result}
}
// getOrCreateSubrange gets a metadata node for the specified subrange,
// creating if required.
func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
return Metadata{C: result}
}
// getOrCreateArray gets a metadata node containing the specified values,
// creating if required.
func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
if len(values) == 0 {
return Metadata{}
}
data, length := llvmMetadataRefs(values)
result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
return Metadata{C: result}
}
// getOrCreateTypeArray gets a metadata node for a type array containing the
// specified values, creating if required.
func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
if len(values) == 0 {
return Metadata{}
}
data, length := llvmMetadataRefs(values)
result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
return Metadata{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) Metadata {
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 Metadata{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 Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) Value {
loc := C.LLVMDIBuilderCreateDebugLocation(
d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C)
result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C)
return Value{C: result}
}
// InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
// specified basic block for the given value and associated debug metadata.
func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) Value {
loc := C.LLVMDIBuilderCreateDebugLocation(
d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C)
result := C.LLVMDIBuilderInsertDbgValueAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C)
return Value{C: result}
}
func (v Value) SetSubprogram(sp Metadata) {
C.LLVMSetSubprogram(v.C, sp.C)
}
func boolToCInt(v bool) C.int {
if v {
return 1
}
return 0
}
//-------------------------------------------------------------------------
// llvm.Metadata
//-------------------------------------------------------------------------
func (c Context) TemporaryMDNode(mds []Metadata) (md Metadata) {
ptr, nvals := llvmMetadataRefs(mds)
md.C = C.LLVMTemporaryMDNode(c.C, ptr, C.size_t(nvals))
return
}
func (md Metadata) ReplaceAllUsesWith(new Metadata) {
C.LLVMMetadataReplaceAllUsesWith(md.C, new.C)
}