dibuilder.go raw

   1  //===- dibuilder.go - Bindings for DIBuilder ------------------------------===//
   2  //
   3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
   4  // See https://llvm.org/LICENSE.txt for license information.
   5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
   6  //
   7  //===----------------------------------------------------------------------===//
   8  //
   9  // This file defines bindings for the DIBuilder class.
  10  //
  11  //===----------------------------------------------------------------------===//
  12  
  13  package llvm
  14  
  15  /*
  16  #include "IRBindings.h"
  17  #include "backports.h"
  18  #include <stdlib.h>
  19  */
  20  import "C"
  21  
  22  import (
  23  	"debug/dwarf"
  24  	"unsafe"
  25  )
  26  
  27  type DwarfTag uint32
  28  
  29  const (
  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
  41  )
  42  
  43  const (
  44  	FlagPrivate = 1 << iota
  45  	FlagProtected
  46  	FlagFwdDecl
  47  	FlagAppleBlock
  48  	FlagReserved
  49  	FlagVirtual
  50  	FlagArtificial
  51  	FlagExplicit
  52  	FlagPrototyped
  53  	FlagObjcClassComplete
  54  	FlagObjectPointer
  55  	FlagVector
  56  	FlagStaticMember
  57  	FlagIndirectVariable
  58  )
  59  
  60  type DwarfLang uint32
  61  
  62  const (
  63  	// http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open
  64  	DW_LANG_Go DwarfLang = 0x0016
  65  )
  66  
  67  type DwarfTypeEncoding uint32
  68  
  69  const (
  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
  88  )
  89  
  90  // DIBuilder is a wrapper for the LLVM DIBuilder class.
  91  type DIBuilder struct {
  92  	ref C.LLVMDIBuilderRef
  93  	m   Module
  94  }
  95  
  96  // NewDIBuilder creates a new DIBuilder, associated with the given module.
  97  func NewDIBuilder(m Module) *DIBuilder {
  98  	d := C.LLVMCreateDIBuilder(m.C)
  99  	return &DIBuilder{ref: d, m: m}
 100  }
 101  
 102  // Destroy destroys the DIBuilder.
 103  func (d *DIBuilder) Destroy() {
 104  	C.LLVMDisposeDIBuilder(d.ref)
 105  }
 106  
 107  // FInalize finalizes the debug information generated by the DIBuilder.
 108  func (d *DIBuilder) Finalize() {
 109  	C.LLVMDIBuilderFinalize(d.ref)
 110  }
 111  
 112  // DICompileUnit holds the values for creating compile unit debug metadata.
 113  type DICompileUnit struct {
 114  	Language       DwarfLang
 115  	File           string
 116  	Dir            string
 117  	Producer       string
 118  	Optimized      bool
 119  	Flags          string
 120  	RuntimeVersion int
 121  	SysRoot        string
 122  	SDK            string
 123  }
 124  
 125  // CreateCompileUnit creates compile unit debug metadata.
 126  func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata {
 127  	file := C.CString(cu.File)
 128  	defer C.free(unsafe.Pointer(file))
 129  	dir := C.CString(cu.Dir)
 130  	defer C.free(unsafe.Pointer(dir))
 131  	producer := C.CString(cu.Producer)
 132  	defer C.free(unsafe.Pointer(producer))
 133  	flags := C.CString(cu.Flags)
 134  	defer C.free(unsafe.Pointer(flags))
 135  	sysroot := C.CString(cu.SysRoot)
 136  	defer C.free(unsafe.Pointer(sysroot))
 137  	sdk := C.CString(cu.SDK)
 138  	defer C.free(unsafe.Pointer(sdk))
 139  	result := C.LLVMDIBuilderCreateCompileUnit(
 140  		d.ref,
 141  		C.LLVMDWARFSourceLanguage(cu.Language),
 142  		C.LLVMDIBuilderCreateFile(d.ref, file, C.size_t(len(cu.File)), dir, C.size_t(len(cu.Dir))),
 143  		producer, C.size_t(len(cu.Producer)),
 144  		C.LLVMBool(boolToCInt(cu.Optimized)),
 145  		flags, C.size_t(len(cu.Flags)),
 146  		C.unsigned(cu.RuntimeVersion),
 147  		/*SplitName=*/ nil, 0,
 148  		C.LLVMDWARFEmissionFull,
 149  		/*DWOId=*/ 0,
 150  		/*SplitDebugInlining*/ C.LLVMBool(boolToCInt(true)),
 151  		/*DebugInfoForProfiling*/ C.LLVMBool(boolToCInt(false)),
 152  		sysroot, C.size_t(len(cu.SysRoot)),
 153  		sdk, C.size_t(len(cu.SDK)),
 154  	)
 155  	return Metadata{C: result}
 156  }
 157  
 158  // CreateFile creates file debug metadata.
 159  func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
 160  	cfilename := C.CString(filename)
 161  	defer C.free(unsafe.Pointer(cfilename))
 162  	cdir := C.CString(dir)
 163  	defer C.free(unsafe.Pointer(cdir))
 164  	result := C.LLVMDIBuilderCreateFile(d.ref,
 165  		cfilename, C.size_t(len(filename)),
 166  		cdir, C.size_t(len(dir)))
 167  	return Metadata{C: result}
 168  }
 169  
 170  // DILexicalBlock holds the values for creating lexical block debug metadata.
 171  type DILexicalBlock struct {
 172  	File   Metadata
 173  	Line   int
 174  	Column int
 175  }
 176  
 177  // CreateLexicalBlock creates lexical block debug metadata.
 178  func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
 179  	result := C.LLVMDIBuilderCreateLexicalBlock(
 180  		d.ref,
 181  		diScope.C,
 182  		b.File.C,
 183  		C.unsigned(b.Line),
 184  		C.unsigned(b.Column),
 185  	)
 186  	return Metadata{C: result}
 187  }
 188  
 189  func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata {
 190  	result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
 191  		C.unsigned(discriminator))
 192  	return Metadata{C: result}
 193  }
 194  
 195  // DIFunction holds the values for creating function debug metadata.
 196  type DIFunction struct {
 197  	Name         string
 198  	LinkageName  string
 199  	File         Metadata
 200  	Line         int
 201  	Type         Metadata
 202  	LocalToUnit  bool
 203  	IsDefinition bool
 204  	ScopeLine    int
 205  	Flags        int
 206  	Optimized    bool
 207  }
 208  
 209  // CreateFunction creates function debug metadata.
 210  func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata {
 211  	name := C.CString(f.Name)
 212  	defer C.free(unsafe.Pointer(name))
 213  	linkageName := C.CString(f.LinkageName)
 214  	defer C.free(unsafe.Pointer(linkageName))
 215  	result := C.LLVMDIBuilderCreateFunction(
 216  		d.ref,
 217  		diScope.C,
 218  		name, C.size_t(len(f.Name)),
 219  		linkageName, C.size_t(len(f.LinkageName)),
 220  		f.File.C,
 221  		C.unsigned(f.Line),
 222  		f.Type.C,
 223  		C.LLVMBool(boolToCInt(f.LocalToUnit)),
 224  		C.LLVMBool(boolToCInt(f.IsDefinition)),
 225  		C.unsigned(f.ScopeLine),
 226  		C.LLVMDIFlags(f.Flags),
 227  		C.LLVMBool(boolToCInt(f.Optimized)),
 228  	)
 229  	return Metadata{C: result}
 230  }
 231  
 232  // DIGlobalVariableExpression holds the values for creating global variable
 233  // debug metadata.
 234  type DIGlobalVariableExpression struct {
 235  	Name        string   // Name of the variable.
 236  	LinkageName string   // Mangled name of the variable
 237  	File        Metadata // File where this variable is defined.
 238  	Line        int      // Line number.
 239  	Type        Metadata // Variable Type.
 240  	LocalToUnit bool     // Flag indicating whether this variable is externally visible or not.
 241  	Expr        Metadata // The location of the global relative to the attached GlobalVariable.
 242  	Decl        Metadata // Reference to the corresponding declaration.
 243  	AlignInBits uint32   // Variable alignment(or 0 if no alignment attr was specified).
 244  }
 245  
 246  // CreateGlobalVariableExpression creates a new descriptor for the specified
 247  // global variable.
 248  func (d *DIBuilder) CreateGlobalVariableExpression(diScope Metadata, g DIGlobalVariableExpression) Metadata {
 249  	name := C.CString(g.Name)
 250  	defer C.free(unsafe.Pointer(name))
 251  	linkageName := C.CString(g.LinkageName)
 252  	defer C.free(unsafe.Pointer(linkageName))
 253  	result := C.LLVMDIBuilderCreateGlobalVariableExpression(
 254  		d.ref,                       // Builder
 255  		diScope.C,                   // Scope
 256  		name, C.size_t(len(g.Name)), // Name, NameLen
 257  		linkageName, C.size_t(len(g.LinkageName)), // Linkage, LinkLen
 258  		g.File.C,                              // File
 259  		C.unsigned(g.Line),                    // LineNo
 260  		g.Type.C,                              // Ty
 261  		C.LLVMBool(boolToCInt(g.LocalToUnit)), // LocalToUnit
 262  		g.Expr.C,                              // Expr
 263  		g.Decl.C,                              // Decl
 264  		C.uint32_t(g.AlignInBits),             // AlignInBits
 265  	)
 266  	return Metadata{C: result}
 267  }
 268  
 269  // DIAutoVariable holds the values for creating auto variable debug metadata.
 270  type DIAutoVariable struct {
 271  	Name           string
 272  	File           Metadata
 273  	Line           int
 274  	Type           Metadata
 275  	AlwaysPreserve bool
 276  	Flags          int
 277  	AlignInBits    uint32
 278  }
 279  
 280  // CreateAutoVariable creates local variable debug metadata.
 281  func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
 282  	name := C.CString(v.Name)
 283  	defer C.free(unsafe.Pointer(name))
 284  	result := C.LLVMDIBuilderCreateAutoVariable(
 285  		d.ref,
 286  		scope.C,
 287  		name, C.size_t(len(v.Name)),
 288  		v.File.C,
 289  		C.unsigned(v.Line),
 290  		v.Type.C,
 291  		C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
 292  		C.LLVMDIFlags(v.Flags),
 293  		C.uint32_t(v.AlignInBits),
 294  	)
 295  	return Metadata{C: result}
 296  }
 297  
 298  // DIParameterVariable holds the values for creating parameter variable debug metadata.
 299  type DIParameterVariable struct {
 300  	Name           string
 301  	File           Metadata
 302  	Line           int
 303  	Type           Metadata
 304  	AlwaysPreserve bool
 305  	Flags          int
 306  
 307  	// ArgNo is the 1-based index of the argument in the function's
 308  	// parameter list.
 309  	ArgNo int
 310  }
 311  
 312  // CreateParameterVariable creates parameter variable debug metadata.
 313  func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
 314  	name := C.CString(v.Name)
 315  	defer C.free(unsafe.Pointer(name))
 316  	result := C.LLVMDIBuilderCreateParameterVariable(
 317  		d.ref,
 318  		scope.C,
 319  		name, C.size_t(len(v.Name)),
 320  		C.unsigned(v.ArgNo),
 321  		v.File.C,
 322  		C.unsigned(v.Line),
 323  		v.Type.C,
 324  		C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
 325  		C.LLVMDIFlags(v.Flags),
 326  	)
 327  	return Metadata{C: result}
 328  }
 329  
 330  // DIBasicType holds the values for creating basic type debug metadata.
 331  type DIBasicType struct {
 332  	Name       string
 333  	SizeInBits uint64
 334  	Encoding   DwarfTypeEncoding
 335  }
 336  
 337  // CreateBasicType creates basic type debug metadata.
 338  func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
 339  	name := C.CString(t.Name)
 340  	defer C.free(unsafe.Pointer(name))
 341  	result := C.LLVMDIBuilderCreateBasicType(
 342  		d.ref,
 343  		name,
 344  		C.size_t(len(t.Name)),
 345  		C.uint64_t(t.SizeInBits),
 346  		C.LLVMDWARFTypeEncoding(t.Encoding),
 347  		C.LLVMDIFlags(0),
 348  	)
 349  	return Metadata{C: result}
 350  }
 351  
 352  // DIPointerType holds the values for creating pointer type debug metadata.
 353  type DIPointerType struct {
 354  	Pointee      Metadata
 355  	SizeInBits   uint64
 356  	AlignInBits  uint32 // optional
 357  	AddressSpace uint32
 358  	Name         string // optional
 359  }
 360  
 361  // CreatePointerType creates a type that represents a pointer to another type.
 362  func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
 363  	name := C.CString(t.Name)
 364  	defer C.free(unsafe.Pointer(name))
 365  	result := C.LLVMDIBuilderCreatePointerType(
 366  		d.ref,
 367  		t.Pointee.C,
 368  		C.uint64_t(t.SizeInBits),
 369  		C.uint32_t(t.AlignInBits),
 370  		C.unsigned(t.AddressSpace),
 371  		name,
 372  		C.size_t(len(t.Name)),
 373  	)
 374  	return Metadata{C: result}
 375  }
 376  
 377  // DISubroutineType holds the values for creating subroutine type debug metadata.
 378  type DISubroutineType struct {
 379  	// File is the file in which the subroutine type is defined.
 380  	File Metadata
 381  
 382  	// Parameters contains the subroutine parameter types,
 383  	// including the return type at the 0th index.
 384  	Parameters []Metadata
 385  
 386  	Flags int
 387  }
 388  
 389  // CreateSubroutineType creates subroutine type debug metadata.
 390  func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
 391  	params, length := llvmMetadataRefs(t.Parameters)
 392  	result := C.LLVMDIBuilderCreateSubroutineType(
 393  		d.ref,
 394  		t.File.C,
 395  		params,
 396  		length,
 397  		C.LLVMDIFlags(t.Flags),
 398  	)
 399  	return Metadata{C: result}
 400  }
 401  
 402  // DIStructType holds the values for creating struct type debug metadata.
 403  type DIStructType struct {
 404  	Name         string
 405  	File         Metadata
 406  	Line         int
 407  	SizeInBits   uint64
 408  	AlignInBits  uint32
 409  	Flags        int
 410  	DerivedFrom  Metadata
 411  	Elements     []Metadata
 412  	VTableHolder Metadata // optional
 413  	UniqueID     string
 414  }
 415  
 416  // CreateStructType creates struct type debug metadata.
 417  func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
 418  	elements, length := llvmMetadataRefs(t.Elements)
 419  	name := C.CString(t.Name)
 420  	uniqueID := C.CString(t.UniqueID)
 421  	defer C.free(unsafe.Pointer(name))
 422  	defer C.free(unsafe.Pointer(uniqueID))
 423  	result := C.LLVMDIBuilderCreateStructType(
 424  		d.ref,
 425  		scope.C,
 426  		name,
 427  		C.size_t(len(t.Name)),
 428  		t.File.C,
 429  		C.unsigned(t.Line),
 430  		C.uint64_t(t.SizeInBits),
 431  		C.uint32_t(t.AlignInBits),
 432  		C.LLVMDIFlags(t.Flags),
 433  		t.DerivedFrom.C,
 434  		elements,
 435  		length,
 436  		C.unsigned(0), // Optional Objective-C runtime version.
 437  		t.VTableHolder.C,
 438  		uniqueID,
 439  		C.size_t(len(t.UniqueID)),
 440  	)
 441  	return Metadata{C: result}
 442  }
 443  
 444  // DIReplaceableCompositeType holds the values for creating replaceable
 445  // composite type debug metadata.
 446  type DIReplaceableCompositeType struct {
 447  	Tag         dwarf.Tag
 448  	Name        string
 449  	File        Metadata
 450  	Line        int
 451  	RuntimeLang int
 452  	SizeInBits  uint64
 453  	AlignInBits uint32
 454  	Flags       int
 455  	UniqueID    string
 456  }
 457  
 458  // CreateReplaceableCompositeType creates replaceable composite type debug metadata.
 459  func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
 460  	name := C.CString(t.Name)
 461  	uniqueID := C.CString(t.UniqueID)
 462  	defer C.free(unsafe.Pointer(name))
 463  	defer C.free(unsafe.Pointer(uniqueID))
 464  	result := C.LLVMDIBuilderCreateReplaceableCompositeType(
 465  		d.ref,
 466  		C.unsigned(t.Tag),
 467  		name,
 468  		C.size_t(len(t.Name)),
 469  		scope.C,
 470  		t.File.C,
 471  		C.unsigned(t.Line),
 472  		C.unsigned(t.RuntimeLang),
 473  		C.uint64_t(t.SizeInBits),
 474  		C.uint32_t(t.AlignInBits),
 475  		C.LLVMDIFlags(t.Flags),
 476  		uniqueID,
 477  		C.size_t(len(t.UniqueID)),
 478  	)
 479  	return Metadata{C: result}
 480  }
 481  
 482  // DIMemberType holds the values for creating member type debug metadata.
 483  type DIMemberType struct {
 484  	Name         string
 485  	File         Metadata
 486  	Line         int
 487  	SizeInBits   uint64
 488  	AlignInBits  uint32
 489  	OffsetInBits uint64
 490  	Flags        int
 491  	Type         Metadata
 492  }
 493  
 494  // CreateMemberType creates struct type debug metadata.
 495  func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
 496  	name := C.CString(t.Name)
 497  	defer C.free(unsafe.Pointer(name))
 498  	result := C.LLVMDIBuilderCreateMemberType(
 499  		d.ref,
 500  		scope.C,
 501  		name,
 502  		C.size_t(len(t.Name)),
 503  		t.File.C,
 504  		C.unsigned(t.Line),
 505  		C.uint64_t(t.SizeInBits),
 506  		C.uint32_t(t.AlignInBits),
 507  		C.uint64_t(t.OffsetInBits),
 508  		C.LLVMDIFlags(t.Flags),
 509  		t.Type.C,
 510  	)
 511  	return Metadata{C: result}
 512  }
 513  
 514  // DISubrange describes an integer value range.
 515  type DISubrange struct {
 516  	Lo    int64
 517  	Count int64
 518  }
 519  
 520  // DIArrayType holds the values for creating array type debug metadata.
 521  type DIArrayType struct {
 522  	SizeInBits  uint64
 523  	AlignInBits uint32
 524  	ElementType Metadata
 525  	Subscripts  []DISubrange
 526  }
 527  
 528  // CreateArrayType creates struct type debug metadata.
 529  func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
 530  	subscriptsSlice := make([]Metadata, len(t.Subscripts))
 531  	for i, s := range t.Subscripts {
 532  		subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
 533  	}
 534  	subscripts, length := llvmMetadataRefs(subscriptsSlice)
 535  	result := C.LLVMDIBuilderCreateArrayType(
 536  		d.ref,
 537  		C.uint64_t(t.SizeInBits),
 538  		C.uint32_t(t.AlignInBits),
 539  		t.ElementType.C,
 540  		subscripts,
 541  		length,
 542  	)
 543  	return Metadata{C: result}
 544  }
 545  
 546  // DITypedef holds the values for creating typedef type debug metadata.
 547  type DITypedef struct {
 548  	Type        Metadata
 549  	Name        string
 550  	File        Metadata
 551  	Line        int
 552  	Context     Metadata
 553  	AlignInBits uint32
 554  }
 555  
 556  // CreateTypedef creates typedef type debug metadata.
 557  func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
 558  	name := C.CString(t.Name)
 559  	defer C.free(unsafe.Pointer(name))
 560  	result := C.LLVMDIBuilderCreateTypedef(
 561  		d.ref,
 562  		t.Type.C,
 563  		name,
 564  		C.size_t(len(t.Name)),
 565  		t.File.C,
 566  		C.unsigned(t.Line),
 567  		t.Context.C,
 568  		C.uint32_t(t.AlignInBits),
 569  	)
 570  	return Metadata{C: result}
 571  }
 572  
 573  // getOrCreateSubrange gets a metadata node for the specified subrange,
 574  // creating if required.
 575  func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
 576  	result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
 577  	return Metadata{C: result}
 578  }
 579  
 580  // getOrCreateArray gets a metadata node containing the specified values,
 581  // creating if required.
 582  func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
 583  	if len(values) == 0 {
 584  		return Metadata{}
 585  	}
 586  	data, length := llvmMetadataRefs(values)
 587  	result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
 588  	return Metadata{C: result}
 589  }
 590  
 591  // getOrCreateTypeArray gets a metadata node for a type array containing the
 592  // specified values, creating if required.
 593  func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
 594  	if len(values) == 0 {
 595  		return Metadata{}
 596  	}
 597  	data, length := llvmMetadataRefs(values)
 598  	result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
 599  	return Metadata{C: result}
 600  }
 601  
 602  // CreateExpression creates a new descriptor for the specified
 603  // variable which has a complex address expression for its address.
 604  func (d *DIBuilder) CreateExpression(addr []uint64) Metadata {
 605  	var data *C.uint64_t
 606  	if len(addr) > 0 {
 607  		data = (*C.uint64_t)(unsafe.Pointer(&addr[0]))
 608  	}
 609  	result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
 610  	return Metadata{C: result}
 611  }
 612  
 613  // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
 614  // specified basic block for the given value and associated debug metadata.
 615  func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) {
 616  	loc := C.LLVMDIBuilderCreateDebugLocation(
 617  		d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C)
 618  	C.LLVMGoDIBuilderInsertDbgValueRecordAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C)
 619  }
 620  
 621  func (v Value) SetSubprogram(sp Metadata) {
 622  	C.LLVMSetSubprogram(v.C, sp.C)
 623  }
 624  
 625  func (v Value) Subprogram() (md Metadata) {
 626  	md.C = C.LLVMGetSubprogram(v.C)
 627  	return
 628  }
 629  
 630  // AddMetadata adds a metadata entry of the given kind to a global object.
 631  func (v Value) AddMetadata(kind int, md Metadata) {
 632  	C.LLVMGlobalObjectAddMetadata(v.C, C.unsigned(kind), md.C)
 633  }
 634  
 635  func boolToCInt(v bool) C.int {
 636  	if v {
 637  		return 1
 638  	}
 639  	return 0
 640  }
 641  
 642  //-------------------------------------------------------------------------
 643  // llvm.Metadata
 644  //-------------------------------------------------------------------------
 645  
 646  func (c Context) TemporaryMDNode(mds []Metadata) (md Metadata) {
 647  	ptr, nvals := llvmMetadataRefs(mds)
 648  	md.C = C.LLVMTemporaryMDNode(c.C, ptr, C.size_t(nvals))
 649  	return
 650  }
 651  
 652  func (md Metadata) ReplaceAllUsesWith(new Metadata) {
 653  	C.LLVMMetadataReplaceAllUsesWith(md.C, new.C)
 654  }
 655  
 656  type MetadataKind C.LLVMMetadataKind
 657  
 658  const (
 659  	MDStringMetadataKind                     = C.LLVMMDStringMetadataKind
 660  	ConstantAsMetadataMetadataKind           = C.LLVMConstantAsMetadataMetadataKind
 661  	LocalAsMetadataMetadataKind              = C.LLVMLocalAsMetadataMetadataKind
 662  	DistinctMDOperandPlaceholderMetadataKind = C.LLVMDistinctMDOperandPlaceholderMetadataKind
 663  	MDTupleMetadataKind                      = C.LLVMMDTupleMetadataKind
 664  	DILocationMetadataKind                   = C.LLVMDILocationMetadataKind
 665  	DIExpressionMetadataKind                 = C.LLVMDIExpressionMetadataKind
 666  	DIGlobalVariableExpressionMetadataKind   = C.LLVMDIGlobalVariableExpressionMetadataKind
 667  	GenericDINodeMetadataKind                = C.LLVMGenericDINodeMetadataKind
 668  	DISubrangeMetadataKind                   = C.LLVMDISubrangeMetadataKind
 669  	DIEnumeratorMetadataKind                 = C.LLVMDIEnumeratorMetadataKind
 670  	DIBasicTypeMetadataKind                  = C.LLVMDIBasicTypeMetadataKind
 671  	DIDerivedTypeMetadataKind                = C.LLVMDIDerivedTypeMetadataKind
 672  	DICompositeTypeMetadataKind              = C.LLVMDICompositeTypeMetadataKind
 673  	DISubroutineTypeMetadataKind             = C.LLVMDISubroutineTypeMetadataKind
 674  	DIFileMetadataKind                       = C.LLVMDIFileMetadataKind
 675  	DICompileUnitMetadataKind                = C.LLVMDICompileUnitMetadataKind
 676  	DISubprogramMetadataKind                 = C.LLVMDISubprogramMetadataKind
 677  	DILexicalBlockMetadataKind               = C.LLVMDILexicalBlockMetadataKind
 678  	DILexicalBlockFileMetadataKind           = C.LLVMDILexicalBlockFileMetadataKind
 679  	DINamespaceMetadataKind                  = C.LLVMDINamespaceMetadataKind
 680  	DIModuleMetadataKind                     = C.LLVMDIModuleMetadataKind
 681  	DITemplateTypeParameterMetadataKind      = C.LLVMDITemplateTypeParameterMetadataKind
 682  	DITemplateValueParameterMetadataKind     = C.LLVMDITemplateValueParameterMetadataKind
 683  	DIGlobalVariableMetadataKind             = C.LLVMDIGlobalVariableMetadataKind
 684  	DILocalVariableMetadataKind              = C.LLVMDILocalVariableMetadataKind
 685  	DILabelMetadataKind                      = C.LLVMDILabelMetadataKind
 686  	DIObjCPropertyMetadataKind               = C.LLVMDIObjCPropertyMetadataKind
 687  	DIImportedEntityMetadataKind             = C.LLVMDIImportedEntityMetadataKind
 688  	DIMacroMetadataKind                      = C.LLVMDIMacroMetadataKind
 689  	DIMacroFileMetadataKind                  = C.LLVMDIMacroFileMetadataKind
 690  	DICommonBlockMetadataKind                = C.LLVMDICommonBlockMetadataKind
 691  )
 692  
 693  // Kind returns the metadata kind.
 694  func (md Metadata) Kind() MetadataKind {
 695  	return MetadataKind(C.LLVMGetMetadataKind(md.C))
 696  }
 697  
 698  // FileDirectory returns the directory of a DIFile metadata node, or the empty
 699  // string if there is no directory information.
 700  func (md Metadata) FileDirectory() string {
 701  	var length C.unsigned
 702  	ptr := C.LLVMDIFileGetDirectory(md.C, &length)
 703  	if ptr == nil {
 704  		return ""
 705  	}
 706  	return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
 707  }
 708  
 709  // FileFilename returns the filename of a DIFile metadata node, or the empty
 710  // string if there is no filename information.
 711  func (md Metadata) FileFilename() string {
 712  	var length C.unsigned
 713  	ptr := C.LLVMDIFileGetFilename(md.C, &length)
 714  	if ptr == nil {
 715  		return ""
 716  	}
 717  	return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
 718  }
 719  
 720  // FileSource returns the source of a DIFile metadata node.
 721  func (md Metadata) FileSource() string {
 722  	var length C.unsigned
 723  	ptr := C.LLVMDIFileGetSource(md.C, &length)
 724  	if ptr == nil {
 725  		return ""
 726  	}
 727  	return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
 728  }
 729  
 730  // LocationLine returns the line number of a DILocation.
 731  func (md Metadata) LocationLine() uint {
 732  	return uint(C.LLVMDILocationGetLine(md.C))
 733  }
 734  
 735  // LocationColumn returns the column (offset from the start of the line) of a
 736  // DILocation.
 737  func (md Metadata) LocationColumn() uint {
 738  	return uint(C.LLVMDILocationGetColumn(md.C))
 739  }
 740  
 741  // LocationScope returns the local scope associated with this debug location.
 742  func (md Metadata) LocationScope() Metadata {
 743  	return Metadata{C.LLVMDILocationGetScope(md.C)}
 744  }
 745  
 746  // LocationInlinedAt return the "inline at" location associated with this debug
 747  // location.
 748  func (md Metadata) LocationInlinedAt() Metadata {
 749  	return Metadata{C.LLVMDILocationGetInlinedAt(md.C)}
 750  }
 751  
 752  // ScopeFile returns the file (DIFile) of a given scope.
 753  func (md Metadata) ScopeFile() Metadata {
 754  	return Metadata{C.LLVMDIScopeGetFile(md.C)}
 755  }
 756  
 757  // SubprogramLine returns the line number of a DISubprogram.
 758  func (md Metadata) SubprogramLine() uint {
 759  	return uint(C.LLVMDISubprogramGetLine(md.C))
 760  }
 761