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