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
13package llvm
14
15/*
16#include "IRBindings.h"
17#include "backports.h"
18#include <stdlib.h>
19*/
20import "C"
21
22import (
23	"debug/dwarf"
24	"unsafe"
25)
26
27type DwarfTag uint32
28
29const (
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
43const (
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
60type DwarfLang uint32
61
62const (
63	// http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open
64	DW_LANG_Go DwarfLang = 0x0016
65)
66
67type DwarfTypeEncoding uint32
68
69const (
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.
91type DIBuilder struct {
92	ref C.LLVMDIBuilderRef
93	m   Module
94}
95
96// NewDIBuilder creates a new DIBuilder, associated with the given module.
97func NewDIBuilder(m Module) *DIBuilder {
98	d := C.LLVMCreateDIBuilder(m.C)
99	return &DIBuilder{ref: d, m: m}
100}
101
102// Destroy destroys the DIBuilder.
103func (d *DIBuilder) Destroy() {
104	C.LLVMDisposeDIBuilder(d.ref)
105}
106
107// FInalize finalizes the debug information generated by the DIBuilder.
108func (d *DIBuilder) Finalize() {
109	C.LLVMDIBuilderFinalize(d.ref)
110}
111
112// DICompileUnit holds the values for creating compile unit debug metadata.
113type DICompileUnit struct {
114	Language       DwarfLang
115	File           string
116	Dir            string
117	Producer       string
118	Optimized      bool
119	Flags          string
120	RuntimeVersion int
121}
122
123// CreateCompileUnit creates compile unit debug metadata.
124func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata {
125	file := C.CString(cu.File)
126	defer C.free(unsafe.Pointer(file))
127	dir := C.CString(cu.Dir)
128	defer C.free(unsafe.Pointer(dir))
129	producer := C.CString(cu.Producer)
130	defer C.free(unsafe.Pointer(producer))
131	flags := C.CString(cu.Flags)
132	defer C.free(unsafe.Pointer(flags))
133	result := C.LLVMDIBuilderCreateCompileUnit(
134		d.ref,
135		C.LLVMDWARFSourceLanguage(cu.Language),
136		C.LLVMDIBuilderCreateFile(d.ref, file, C.size_t(len(cu.File)), dir, C.size_t(len(cu.Dir))),
137		producer, C.size_t(len(cu.Producer)),
138		C.LLVMBool(boolToCInt(cu.Optimized)),
139		flags, C.size_t(len(cu.Flags)),
140		C.unsigned(cu.RuntimeVersion),
141		/*SplitName=*/ nil, 0,
142		C.LLVMDWARFEmissionFull,
143		/*DWOId=*/ 0,
144		/*SplitDebugInlining*/ C.LLVMBool(boolToCInt(true)),
145		/*DebugInfoForProfiling*/ C.LLVMBool(boolToCInt(false)),
146	)
147	return Metadata{C: result}
148}
149
150// CreateFile creates file debug metadata.
151func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
152	cfilename := C.CString(filename)
153	defer C.free(unsafe.Pointer(cfilename))
154	cdir := C.CString(dir)
155	defer C.free(unsafe.Pointer(cdir))
156	result := C.LLVMDIBuilderCreateFile(d.ref,
157		cfilename, C.size_t(len(filename)),
158		cdir, C.size_t(len(dir)))
159	return Metadata{C: result}
160}
161
162// DILexicalBlock holds the values for creating lexical block debug metadata.
163type DILexicalBlock struct {
164	File   Metadata
165	Line   int
166	Column int
167}
168
169// CreateLexicalBlock creates lexical block debug metadata.
170func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
171	result := C.LLVMDIBuilderCreateLexicalBlock(
172		d.ref,
173		diScope.C,
174		b.File.C,
175		C.unsigned(b.Line),
176		C.unsigned(b.Column),
177	)
178	return Metadata{C: result}
179}
180
181func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata {
182	result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
183		C.unsigned(discriminator))
184	return Metadata{C: result}
185}
186
187// DIFunction holds the values for creating function debug metadata.
188type DIFunction struct {
189	Name         string
190	LinkageName  string
191	File         Metadata
192	Line         int
193	Type         Metadata
194	LocalToUnit  bool
195	IsDefinition bool
196	ScopeLine    int
197	Flags        int
198	Optimized    bool
199}
200
201// CreateFunction creates function debug metadata.
202func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata {
203	name := C.CString(f.Name)
204	defer C.free(unsafe.Pointer(name))
205	linkageName := C.CString(f.LinkageName)
206	defer C.free(unsafe.Pointer(linkageName))
207	result := C.LLVMDIBuilderCreateFunction(
208		d.ref,
209		diScope.C,
210		name, C.size_t(len(f.Name)),
211		linkageName, C.size_t(len(f.LinkageName)),
212		f.File.C,
213		C.unsigned(f.Line),
214		f.Type.C,
215		C.LLVMBool(boolToCInt(f.LocalToUnit)),
216		C.LLVMBool(boolToCInt(f.IsDefinition)),
217		C.unsigned(f.ScopeLine),
218		C.LLVMDIFlags(f.Flags),
219		C.LLVMBool(boolToCInt(f.Optimized)),
220	)
221	return Metadata{C: result}
222}
223
224// DIGlobalVariableExpression holds the values for creating global variable
225// debug metadata.
226type DIGlobalVariableExpression struct {
227	Name        string   // Name of the variable.
228	LinkageName string   // Mangled name of the variable
229	File        Metadata // File where this variable is defined.
230	Line        int      // Line number.
231	Type        Metadata // Variable Type.
232	LocalToUnit bool     // Flag indicating whether this variable is externally visible or not.
233	Expr        Metadata // The location of the global relative to the attached GlobalVariable.
234	Decl        Metadata // Reference to the corresponding declaration.
235	AlignInBits uint32   // Variable alignment(or 0 if no alignment attr was specified).
236}
237
238// CreateGlobalVariableExpression creates a new descriptor for the specified
239// global variable.
240func (d *DIBuilder) CreateGlobalVariableExpression(diScope Metadata, g DIGlobalVariableExpression) Metadata {
241	name := C.CString(g.Name)
242	defer C.free(unsafe.Pointer(name))
243	linkageName := C.CString(g.LinkageName)
244	defer C.free(unsafe.Pointer(linkageName))
245	result := C.LLVMDIBuilderCreateGlobalVariableExpression(
246		d.ref,                       // Builder
247		diScope.C,                   // Scope
248		name, C.size_t(len(g.Name)), // Name, NameLen
249		linkageName, C.size_t(len(g.LinkageName)), // Linkage, LinkLen
250		g.File.C,                              // File
251		C.unsigned(g.Line),                    // LineNo
252		g.Type.C,                              // Ty
253		C.LLVMBool(boolToCInt(g.LocalToUnit)), // LocalToUnit
254		g.Expr.C,                              // Expr
255		g.Decl.C,                              // Decl
256		C.uint32_t(g.AlignInBits),             // AlignInBits
257	)
258	return Metadata{C: result}
259}
260
261// DIAutoVariable holds the values for creating auto variable debug metadata.
262type DIAutoVariable struct {
263	Name           string
264	File           Metadata
265	Line           int
266	Type           Metadata
267	AlwaysPreserve bool
268	Flags          int
269	AlignInBits    uint32
270}
271
272// CreateAutoVariable creates local variable debug metadata.
273func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
274	name := C.CString(v.Name)
275	defer C.free(unsafe.Pointer(name))
276	result := C.LLVMDIBuilderCreateAutoVariable(
277		d.ref,
278		scope.C,
279		name, C.size_t(len(v.Name)),
280		v.File.C,
281		C.unsigned(v.Line),
282		v.Type.C,
283		C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
284		C.LLVMDIFlags(v.Flags),
285		C.uint32_t(v.AlignInBits),
286	)
287	return Metadata{C: result}
288}
289
290// DIParameterVariable holds the values for creating parameter variable debug metadata.
291type DIParameterVariable struct {
292	Name           string
293	File           Metadata
294	Line           int
295	Type           Metadata
296	AlwaysPreserve bool
297	Flags          int
298
299	// ArgNo is the 1-based index of the argument in the function's
300	// parameter list.
301	ArgNo int
302}
303
304// CreateParameterVariable creates parameter variable debug metadata.
305func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
306	name := C.CString(v.Name)
307	defer C.free(unsafe.Pointer(name))
308	result := C.LLVMDIBuilderCreateParameterVariable(
309		d.ref,
310		scope.C,
311		name, C.size_t(len(v.Name)),
312		C.unsigned(v.ArgNo),
313		v.File.C,
314		C.unsigned(v.Line),
315		v.Type.C,
316		C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
317		C.LLVMDIFlags(v.Flags),
318	)
319	return Metadata{C: result}
320}
321
322// DIBasicType holds the values for creating basic type debug metadata.
323type DIBasicType struct {
324	Name       string
325	SizeInBits uint64
326	Encoding   DwarfTypeEncoding
327}
328
329// CreateBasicType creates basic type debug metadata.
330func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
331	name := C.CString(t.Name)
332	defer C.free(unsafe.Pointer(name))
333	result := C.LLVMDIBuilderCreateBasicType(
334		d.ref,
335		name,
336		C.size_t(len(t.Name)),
337		C.uint64_t(t.SizeInBits),
338		C.LLVMDWARFTypeEncoding(t.Encoding),
339		C.LLVMDIFlags(0),
340	)
341	return Metadata{C: result}
342}
343
344// DIPointerType holds the values for creating pointer type debug metadata.
345type DIPointerType struct {
346	Pointee      Metadata
347	SizeInBits   uint64
348	AlignInBits  uint32 // optional
349	AddressSpace uint32
350	Name         string // optional
351}
352
353// CreatePointerType creates a type that represents a pointer to another type.
354func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
355	name := C.CString(t.Name)
356	defer C.free(unsafe.Pointer(name))
357	result := C.LLVMDIBuilderCreatePointerType(
358		d.ref,
359		t.Pointee.C,
360		C.uint64_t(t.SizeInBits),
361		C.uint32_t(t.AlignInBits),
362		C.unsigned(t.AddressSpace),
363		name,
364		C.size_t(len(t.Name)),
365	)
366	return Metadata{C: result}
367}
368
369// DISubroutineType holds the values for creating subroutine type debug metadata.
370type DISubroutineType struct {
371	// File is the file in which the subroutine type is defined.
372	File Metadata
373
374	// Parameters contains the subroutine parameter types,
375	// including the return type at the 0th index.
376	Parameters []Metadata
377
378	Flags int
379}
380
381// CreateSubroutineType creates subroutine type debug metadata.
382func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
383	params, length := llvmMetadataRefs(t.Parameters)
384	result := C.LLVMDIBuilderCreateSubroutineType(
385		d.ref,
386		t.File.C,
387		params,
388		length,
389		C.LLVMDIFlags(t.Flags),
390	)
391	return Metadata{C: result}
392}
393
394// DIStructType holds the values for creating struct type debug metadata.
395type DIStructType struct {
396	Name         string
397	File         Metadata
398	Line         int
399	SizeInBits   uint64
400	AlignInBits  uint32
401	Flags        int
402	DerivedFrom  Metadata
403	Elements     []Metadata
404	VTableHolder Metadata // optional
405	UniqueID     string
406}
407
408// CreateStructType creates struct type debug metadata.
409func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
410	elements, length := llvmMetadataRefs(t.Elements)
411	name := C.CString(t.Name)
412	uniqueID := C.CString(t.UniqueID)
413	defer C.free(unsafe.Pointer(name))
414	defer C.free(unsafe.Pointer(uniqueID))
415	result := C.LLVMDIBuilderCreateStructType(
416		d.ref,
417		scope.C,
418		name,
419		C.size_t(len(t.Name)),
420		t.File.C,
421		C.unsigned(t.Line),
422		C.uint64_t(t.SizeInBits),
423		C.uint32_t(t.AlignInBits),
424		C.LLVMDIFlags(t.Flags),
425		t.DerivedFrom.C,
426		elements,
427		length,
428		C.unsigned(0), // Optional Objective-C runtime version.
429		t.VTableHolder.C,
430		uniqueID,
431		C.size_t(len(t.UniqueID)),
432	)
433	return Metadata{C: result}
434}
435
436// DIReplaceableCompositeType holds the values for creating replaceable
437// composite type debug metadata.
438type DIReplaceableCompositeType struct {
439	Tag         dwarf.Tag
440	Name        string
441	File        Metadata
442	Line        int
443	RuntimeLang int
444	SizeInBits  uint64
445	AlignInBits uint32
446	Flags       int
447	UniqueID    string
448}
449
450// CreateReplaceableCompositeType creates replaceable composite type debug metadata.
451func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
452	name := C.CString(t.Name)
453	uniqueID := C.CString(t.UniqueID)
454	defer C.free(unsafe.Pointer(name))
455	defer C.free(unsafe.Pointer(uniqueID))
456	result := C.LLVMDIBuilderCreateReplaceableCompositeType(
457		d.ref,
458		C.unsigned(t.Tag),
459		name,
460		C.size_t(len(t.Name)),
461		scope.C,
462		t.File.C,
463		C.unsigned(t.Line),
464		C.unsigned(t.RuntimeLang),
465		C.uint64_t(t.SizeInBits),
466		C.uint32_t(t.AlignInBits),
467		C.LLVMDIFlags(t.Flags),
468		uniqueID,
469		C.size_t(len(t.UniqueID)),
470	)
471	return Metadata{C: result}
472}
473
474// DIMemberType holds the values for creating member type debug metadata.
475type DIMemberType struct {
476	Name         string
477	File         Metadata
478	Line         int
479	SizeInBits   uint64
480	AlignInBits  uint32
481	OffsetInBits uint64
482	Flags        int
483	Type         Metadata
484}
485
486// CreateMemberType creates struct type debug metadata.
487func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
488	name := C.CString(t.Name)
489	defer C.free(unsafe.Pointer(name))
490	result := C.LLVMDIBuilderCreateMemberType(
491		d.ref,
492		scope.C,
493		name,
494		C.size_t(len(t.Name)),
495		t.File.C,
496		C.unsigned(t.Line),
497		C.uint64_t(t.SizeInBits),
498		C.uint32_t(t.AlignInBits),
499		C.uint64_t(t.OffsetInBits),
500		C.LLVMDIFlags(t.Flags),
501		t.Type.C,
502	)
503	return Metadata{C: result}
504}
505
506// DISubrange describes an integer value range.
507type DISubrange struct {
508	Lo    int64
509	Count int64
510}
511
512// DIArrayType holds the values for creating array type debug metadata.
513type DIArrayType struct {
514	SizeInBits  uint64
515	AlignInBits uint32
516	ElementType Metadata
517	Subscripts  []DISubrange
518}
519
520// CreateArrayType creates struct type debug metadata.
521func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
522	subscriptsSlice := make([]Metadata, len(t.Subscripts))
523	for i, s := range t.Subscripts {
524		subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
525	}
526	subscripts, length := llvmMetadataRefs(subscriptsSlice)
527	result := C.LLVMDIBuilderCreateArrayType(
528		d.ref,
529		C.uint64_t(t.SizeInBits),
530		C.uint32_t(t.AlignInBits),
531		t.ElementType.C,
532		subscripts,
533		length,
534	)
535	return Metadata{C: result}
536}
537
538// DITypedef holds the values for creating typedef type debug metadata.
539type DITypedef struct {
540	Type        Metadata
541	Name        string
542	File        Metadata
543	Line        int
544	Context     Metadata
545	AlignInBits uint32
546}
547
548// CreateTypedef creates typedef type debug metadata.
549func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
550	name := C.CString(t.Name)
551	defer C.free(unsafe.Pointer(name))
552	result := C.LLVMGoDIBuilderCreateTypedef(
553		d.ref,
554		t.Type.C,
555		name,
556		C.size_t(len(t.Name)),
557		t.File.C,
558		C.unsigned(t.Line),
559		t.Context.C,
560		C.uint32_t(t.AlignInBits),
561	)
562	return Metadata{C: result}
563}
564
565// getOrCreateSubrange gets a metadata node for the specified subrange,
566// creating if required.
567func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
568	result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
569	return Metadata{C: result}
570}
571
572// getOrCreateArray gets a metadata node containing the specified values,
573// creating if required.
574func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
575	if len(values) == 0 {
576		return Metadata{}
577	}
578	data, length := llvmMetadataRefs(values)
579	result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
580	return Metadata{C: result}
581}
582
583// getOrCreateTypeArray gets a metadata node for a type array containing the
584// specified values, creating if required.
585func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
586	if len(values) == 0 {
587		return Metadata{}
588	}
589	data, length := llvmMetadataRefs(values)
590	result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
591	return Metadata{C: result}
592}
593
594// CreateExpression creates a new descriptor for the specified
595// variable which has a complex address expression for its address.
596func (d *DIBuilder) CreateExpression(addr []int64) Metadata {
597	var data *C.int64_t
598	if len(addr) > 0 {
599		data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
600	}
601	result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
602	return Metadata{C: result}
603}
604
605// InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
606// specified basic block for the given value and associated debug metadata.
607func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) Value {
608	loc := C.LLVMDIBuilderCreateDebugLocation(
609		d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C)
610	result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C)
611	return Value{C: result}
612}
613
614// InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
615// specified basic block for the given value and associated debug metadata.
616func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) Value {
617	loc := C.LLVMDIBuilderCreateDebugLocation(
618		d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C)
619	result := C.LLVMDIBuilderInsertDbgValueAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C)
620	return Value{C: result}
621}
622
623func (v Value) SetSubprogram(sp Metadata) {
624	C.LLVMSetSubprogram(v.C, sp.C)
625}
626
627func (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.
633func (v Value) AddMetadata(kind int, md Metadata) {
634	C.LLVMGlobalObjectAddMetadata(v.C, C.unsigned(kind), md.C)
635}
636
637func boolToCInt(v bool) C.int {
638	if v {
639		return 1
640	}
641	return 0
642}
643
644//-------------------------------------------------------------------------
645// llvm.Metadata
646//-------------------------------------------------------------------------
647
648func (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
654func (md Metadata) ReplaceAllUsesWith(new Metadata) {
655	C.LLVMMetadataReplaceAllUsesWith(md.C, new.C)
656}
657
658type MetadataKind C.LLVMMetadataKind
659
660const (
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.
696func (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.
702func (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.
713func (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.
723func (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.
733func (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.
739func (md Metadata) LocationColumn() uint {
740	return uint(C.LLVMDILocationGetColumn(md.C))
741}
742
743// LocationScope returns the local scope associated with this debug location.
744func (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.
750func (md Metadata) LocationInlinedAt() Metadata {
751	return Metadata{C.LLVMDILocationGetInlinedAt(md.C)}
752}
753
754// ScopeFile returns the file (DIFile) of a given scope.
755func (md Metadata) ScopeFile() Metadata {
756	return Metadata{C.LLVMDIScopeGetFile(md.C)}
757}
758
759// SubprogramLine returns the line number of a DISubprogram.
760func (md Metadata) SubprogramLine() uint {
761	return uint(C.LLVMDISubprogramGetLine(md.C))
762}
763