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