dibuilder.go raw

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