inkwell/
debug_info.rs

1//! Debug symbols - `DebugInfoBuilder` interface
2//!
3//! # Example usage
4//!
5//! ## Setting up the module for holding debug info:
6//! ```ignore
7//! let context = Context::create();
8//! let module = context.create_module("bin");
9//!
10//! let debug_metadata_version = context.i32_type().const_int(3, false);
11//! module.add_basic_value_flag(
12//!     "Debug Info Version",
13//!     inkwell::module::FlagBehavior::Warning,
14//!     debug_metadata_version,
15//! );
16//! let builder = context.create_builder();
17//! let (dibuilder, compile_unit) = module.create_debug_info_builder(
18//!     true,
19//!     /* language */ inkwell::debug_info::DWARFSourceLanguage::C,
20//!     /* filename */ "source_file",
21//!     /* directory */ ".",
22//!     /* producer */ "my llvm compiler frontend",
23//!     /* is_optimized */ false,
24//!     /* compiler command line flags */ "",
25//!     /* runtime_ver */ 0,
26//!     /* split_name */ "",
27//!     /* kind */ inkwell::debug_info::DWARFEmissionKind::Full,
28//!     /* dwo_id */ 0,
29//!     /* split_debug_inling */ false,
30//!     /* debug_info_for_profiling */ false,
31//! );
32//! ```
33//! ## Creating function debug info
34//! ```ignore
35//!  let ditype = dibuilder.create_basic_type(
36//!      "type_name",
37//!      0_u64,
38//!      0x00,
39//!      inkwell::debug_info::DIFlags::Public,
40//!  ).unwrap();
41//!  let subroutine_type = dibuilder.create_subroutine_type(
42//!      compile_unit.get_file(),
43//!      /* return type */ Some(ditype.as_type()),
44//!      /* parameter types */ &[],
45//!      inkwell::debug_info::DIFlags::Public,
46//!  );
47//!  let func_scope: DISubprogram<'_> = dibuilder.create_function(
48//!      /* scope */ compile_unit.as_debug_info_scope(),
49//!      /* func name */ "main",
50//!      /* linkage_name */ None,
51//!      /* file */ compile_unit.get_file(),
52//!      /* line_no */ 0,
53//!      /* DIType */ subroutine_type,
54//!      /* is_local_to_unit */ true,
55//!      /* is_definition */ true,
56//!      /* scope_line */ 0,
57//!      /* flags */ inkwell::debug_info::DIFlags::Public,
58//!      /* is_optimized */ false,
59//!  );
60//! ```
61//! The `DISubprogram` value must be attached to the generated `FunctionValue`:
62//! ```ignore
63//! /* after creating function: */
64//!     let fn_val = module.add_function(fn_name_str, fn_type, None);
65//!     fn_val.set_subprogram(func_scope);
66//! ```
67//!
68//! ## Setting debug locations
69//! ```ignore
70//! let lexical_block = dibuilder.create_lexical_block(
71//!         /* scope */ func_scope.as_debug_info_scope(),
72//!         /* file */ compile_unit.get_file(),
73//!         /* line_no */ 0,
74//!         /* column_no */ 0);
75//!
76//! let loc = dibuilder
77//!     .create_debug_location(&context, /* line */ 0, /* column */ 0,
78//!     /* current_scope */ lexical_block.as_debug_info_scope(),
79//!     /* inlined_at */ None);
80//! builder.set_current_debug_location(&context, loc);
81//!
82//! // Create global variable
83//! let gv = module.add_global(context.i64_type(), Some(inkwell::AddressSpace::Global), "gv");
84//!
85//!
86//! let const_v = di.create_constant_expression(10);
87//!
88//! let gv_debug = di.create_global_variable_expression(cu.get_file().as_debug_info_scope(), "gv", "", cu.get_file(), 1, ditype.as_type(), true, Some(const_v), None, 8);
89//!
90//! let meta_value: inkwell::values::BasicMetadataValueEnum = gv_debug.as_metadata_value(&context).into();
91//! let metadata = context.metadata_node(&[meta_value]);
92//! gv.set_metadata(metadata, 0);//dbg
93//!
94//! ```
95//!
96//! ## Finalize debug info
97//! Before any kind of code generation (including verification passes; they generate code and
98//! validate debug info), do:
99//! ```ignore
100//! dibuilder.finalize();
101//! ```
102
103use crate::basic_block::BasicBlock;
104use crate::context::{AsContextRef, Context};
105pub use crate::debug_info::flags::{DIFlags, DIFlagsConstants};
106use crate::module::Module;
107use crate::values::{AsValueRef, BasicValueEnum, InstructionValue, MetadataValue, PointerValue};
108use crate::AddressSpace;
109
110use llvm_sys::core::LLVMMetadataAsValue;
111#[llvm_versions(8..)]
112use llvm_sys::debuginfo::LLVMDIBuilderCreateTypedef;
113pub use llvm_sys::debuginfo::LLVMDWARFTypeEncoding;
114use llvm_sys::debuginfo::LLVMDebugMetadataVersion;
115use llvm_sys::debuginfo::LLVMDisposeDIBuilder;
116use llvm_sys::debuginfo::LLVMMetadataReplaceAllUsesWith;
117use llvm_sys::debuginfo::LLVMTemporaryMDNode;
118use llvm_sys::debuginfo::{LLVMCreateDIBuilder, LLVMCreateDIBuilderDisallowUnresolved};
119use llvm_sys::debuginfo::{
120    LLVMDIBuilderCreateArrayType, LLVMDIBuilderCreateAutoVariable, LLVMDIBuilderCreateBasicType,
121    LLVMDIBuilderCreateCompileUnit, LLVMDIBuilderCreateDebugLocation, LLVMDIBuilderCreateExpression,
122    LLVMDIBuilderCreateFile, LLVMDIBuilderCreateFunction, LLVMDIBuilderCreateLexicalBlock,
123    LLVMDIBuilderCreateMemberType, LLVMDIBuilderCreateNameSpace, LLVMDIBuilderCreateParameterVariable,
124    LLVMDIBuilderCreatePointerType, LLVMDIBuilderCreateReferenceType, LLVMDIBuilderCreateStructType,
125    LLVMDIBuilderCreateSubroutineType, LLVMDIBuilderCreateUnionType, LLVMDIBuilderFinalize,
126    LLVMDIBuilderGetOrCreateSubrange, LLVMDIBuilderInsertDbgValueBefore, LLVMDIBuilderInsertDeclareAtEnd,
127    LLVMDIBuilderInsertDeclareBefore, LLVMDILocationGetColumn, LLVMDILocationGetLine, LLVMDILocationGetScope,
128    LLVMDITypeGetAlignInBits, LLVMDITypeGetOffsetInBits, LLVMDITypeGetSizeInBits,
129};
130#[llvm_versions(8..)]
131use llvm_sys::debuginfo::{LLVMDIBuilderCreateConstantValueExpression, LLVMDIBuilderCreateGlobalVariableExpression};
132use llvm_sys::prelude::{LLVMDIBuilderRef, LLVMMetadataRef};
133use std::convert::TryInto;
134use std::marker::PhantomData;
135use std::ops::Range;
136
137/// Gets the version of debug metadata produced by the current LLVM version.
138pub fn debug_metadata_version() -> libc::c_uint {
139    unsafe { LLVMDebugMetadataVersion() }
140}
141
142/// A builder object to create debug info metadata. Used along with `Builder` while producing
143/// IR. Created by `Module::create_debug_info_builder`. See `debug_info` module level
144/// documentation for more.
145#[derive(Debug, PartialEq, Eq)]
146pub struct DebugInfoBuilder<'ctx> {
147    pub(crate) builder: LLVMDIBuilderRef,
148    _marker: PhantomData<&'ctx Context>,
149}
150
151/// Any kind of debug information scope (i.e. visibility of a source code symbol). Scopes are
152/// created by special `DebugInfoBuilder` methods (eg `create_lexical_block`) and can be turned
153/// into a `DIScope` with the `AsDIScope::as_debug_info_scope` trait method.
154#[derive(Clone, Copy, Debug, PartialEq, Eq)]
155pub struct DIScope<'ctx> {
156    metadata_ref: LLVMMetadataRef,
157    _marker: PhantomData<&'ctx Context>,
158}
159
160impl<'ctx> DIScope<'ctx> {
161    /// Acquires the underlying raw pointer belonging to this `DIScope` type.
162    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
163        self.metadata_ref
164    }
165}
166
167/// Specific scopes (i.e. `DILexicalBlock`) can be turned into a `DIScope` with the
168/// `AsDIScope::as_debug_info_scope` trait method.
169pub trait AsDIScope<'ctx> {
170    #[allow(clippy::wrong_self_convention)]
171    fn as_debug_info_scope(self) -> DIScope<'ctx>;
172}
173
174impl<'ctx> DebugInfoBuilder<'ctx> {
175    pub(crate) fn new(
176        module: &Module,
177        allow_unresolved: bool,
178        language: DWARFSourceLanguage,
179        filename: &str,
180        directory: &str,
181        producer: &str,
182        is_optimized: bool,
183        flags: &str,
184        runtime_ver: libc::c_uint,
185        split_name: &str,
186        kind: DWARFEmissionKind,
187        dwo_id: libc::c_uint,
188        split_debug_inlining: bool,
189        debug_info_for_profiling: bool,
190        #[cfg(any(
191            feature = "llvm11-0",
192            feature = "llvm12-0",
193            feature = "llvm13-0",
194            feature = "llvm14-0",
195            feature = "llvm15-0",
196            feature = "llvm16-0",
197            feature = "llvm17-0",
198            feature = "llvm18-0"
199        ))]
200        sysroot: &str,
201        #[cfg(any(
202            feature = "llvm11-0",
203            feature = "llvm12-0",
204            feature = "llvm13-0",
205            feature = "llvm14-0",
206            feature = "llvm15-0",
207            feature = "llvm16-0",
208            feature = "llvm17-0",
209            feature = "llvm18-0"
210        ))]
211        sdk: &str,
212    ) -> (Self, DICompileUnit<'ctx>) {
213        let builder = unsafe {
214            if allow_unresolved {
215                LLVMCreateDIBuilder(module.module.get())
216            } else {
217                LLVMCreateDIBuilderDisallowUnresolved(module.module.get())
218            }
219        };
220
221        let builder = DebugInfoBuilder {
222            builder,
223            _marker: PhantomData,
224        };
225
226        let file = builder.create_file(filename, directory);
227
228        let cu = builder.create_compile_unit(
229            language,
230            file,
231            producer,
232            is_optimized,
233            flags,
234            runtime_ver,
235            split_name,
236            kind,
237            dwo_id,
238            split_debug_inlining,
239            debug_info_for_profiling,
240            #[cfg(any(
241                feature = "llvm11-0",
242                feature = "llvm12-0",
243                feature = "llvm13-0",
244                feature = "llvm14-0",
245                feature = "llvm15-0",
246                feature = "llvm16-0",
247                feature = "llvm17-0",
248                feature = "llvm18-0"
249            ))]
250            sysroot,
251            #[cfg(any(
252                feature = "llvm11-0",
253                feature = "llvm12-0",
254                feature = "llvm13-0",
255                feature = "llvm14-0",
256                feature = "llvm15-0",
257                feature = "llvm16-0",
258                feature = "llvm17-0",
259                feature = "llvm18-0"
260            ))]
261            sdk,
262        );
263
264        (builder, cu)
265    }
266
267    /// Acquires the underlying raw pointer belonging to this `DebugInfoBuilder` type.
268    pub fn as_mut_ptr(&self) -> LLVMDIBuilderRef {
269        self.builder
270    }
271
272    /// A DICompileUnit provides an anchor for all debugging information generated during this instance of compilation.
273    ///
274    /// * `language` - Source programming language
275    /// * `file` - File info
276    /// * `producer` - Identify the producer of debugging information and code. Usually this is a compiler version string.
277    /// * `is_optimized` - A boolean flag which indicates whether optimization is enabled or not.
278    /// * `flags` - This string lists command line options. This string is directly embedded in debug info output which may be used by a tool analyzing generated debugging information.
279    /// * `runtime_ver` - This indicates runtime version for languages like Objective-C.
280    /// * `split_name` - The name of the file that we'll split debug info out into.
281    /// * `kind` - The kind of debug information to generate.
282    /// * `dwo_id` - The DWOId if this is a split skeleton compile unit.
283    /// * `split_debug_inlining` - Whether to emit inline debug info.
284    /// * `debug_info_for_profiling` - Whether to emit extra debug info for profile collection.
285    fn create_compile_unit(
286        &self,
287        language: DWARFSourceLanguage,
288        file: DIFile<'ctx>,
289        producer: &str,
290        is_optimized: bool,
291        flags: &str,
292        runtime_ver: libc::c_uint,
293        split_name: &str,
294        kind: DWARFEmissionKind,
295        dwo_id: libc::c_uint,
296        split_debug_inlining: bool,
297        debug_info_for_profiling: bool,
298        #[cfg(any(
299            feature = "llvm11-0",
300            feature = "llvm12-0",
301            feature = "llvm13-0",
302            feature = "llvm14-0",
303            feature = "llvm15-0",
304            feature = "llvm16-0",
305            feature = "llvm17-0",
306            feature = "llvm18-0"
307        ))]
308        sysroot: &str,
309        #[cfg(any(
310            feature = "llvm11-0",
311            feature = "llvm12-0",
312            feature = "llvm13-0",
313            feature = "llvm14-0",
314            feature = "llvm15-0",
315            feature = "llvm16-0",
316            feature = "llvm17-0",
317            feature = "llvm18-0"
318        ))]
319        sdk: &str,
320    ) -> DICompileUnit<'ctx> {
321        let metadata_ref = unsafe {
322            #[cfg(any(
323                feature = "llvm4-0",
324                feature = "llvm5-0",
325                feature = "llvm6-0",
326                feature = "llvm7-0",
327                feature = "llvm8-0",
328                feature = "llvm9-0",
329                feature = "llvm10-0"
330            ))]
331            {
332                LLVMDIBuilderCreateCompileUnit(
333                    self.builder,
334                    language.into(),
335                    file.metadata_ref,
336                    producer.as_ptr() as _,
337                    producer.len(),
338                    is_optimized as _,
339                    flags.as_ptr() as _,
340                    flags.len(),
341                    runtime_ver,
342                    split_name.as_ptr() as _,
343                    split_name.len(),
344                    kind.into(),
345                    dwo_id,
346                    split_debug_inlining as _,
347                    debug_info_for_profiling as _,
348                )
349            }
350
351            #[cfg(any(
352                feature = "llvm11-0",
353                feature = "llvm12-0",
354                feature = "llvm13-0",
355                feature = "llvm14-0",
356                feature = "llvm15-0",
357                feature = "llvm16-0",
358                feature = "llvm17-0",
359                feature = "llvm18-0"
360            ))]
361            {
362                LLVMDIBuilderCreateCompileUnit(
363                    self.builder,
364                    language.into(),
365                    file.metadata_ref,
366                    producer.as_ptr() as _,
367                    producer.len(),
368                    is_optimized as _,
369                    flags.as_ptr() as _,
370                    flags.len(),
371                    runtime_ver,
372                    split_name.as_ptr() as _,
373                    split_name.len(),
374                    kind.into(),
375                    dwo_id,
376                    split_debug_inlining as _,
377                    debug_info_for_profiling as _,
378                    sysroot.as_ptr() as _,
379                    sysroot.len(),
380                    sdk.as_ptr() as _,
381                    sdk.len(),
382                )
383            }
384        };
385
386        DICompileUnit {
387            file,
388            metadata_ref,
389            _marker: PhantomData,
390        }
391    }
392
393    /// A DIFunction provides an anchor for all debugging information generated for the specified subprogram.
394    ///
395    /// * `scope` - Function scope.
396    /// * `name` - Function name.
397    /// * `linkage_name` - Mangled function name, if any.
398    /// * `file` - File where this variable is defined.
399    /// * `line_no` - Line number.
400    /// * `ty` - Function type.
401    /// * `is_local_to_unit` - True if this function is not externally visible.
402    /// * `is_definition` - True if this is a function definition ("When isDefinition: false,
403    ///   subprograms describe a declaration in the type tree as opposed to a definition of a
404    ///   function").
405    /// * `scope_line` - Set to the beginning of the scope this starts
406    /// * `flags` - E.g.: LLVMDIFlagLValueReference. These flags are used to emit dwarf attributes.
407    /// * `is_optimized` - True if optimization is ON.
408    pub fn create_function(
409        &self,
410        scope: DIScope<'ctx>,
411        name: &str,
412        linkage_name: Option<&str>,
413        file: DIFile<'ctx>,
414        line_no: u32,
415        ditype: DISubroutineType<'ctx>,
416        is_local_to_unit: bool,
417        is_definition: bool,
418        scope_line: u32,
419        flags: DIFlags,
420        is_optimized: bool,
421    ) -> DISubprogram<'ctx> {
422        let linkage_name = linkage_name.unwrap_or(name);
423
424        let metadata_ref = unsafe {
425            LLVMDIBuilderCreateFunction(
426                self.builder,
427                scope.metadata_ref,
428                name.as_ptr() as _,
429                name.len(),
430                linkage_name.as_ptr() as _,
431                linkage_name.len(),
432                file.metadata_ref,
433                line_no,
434                ditype.metadata_ref,
435                is_local_to_unit as _,
436                is_definition as _,
437                scope_line as libc::c_uint,
438                flags,
439                is_optimized as _,
440            )
441        };
442        DISubprogram {
443            metadata_ref,
444            _marker: PhantomData,
445        }
446    }
447
448    /// Create a lexical block scope.
449    pub fn create_lexical_block(
450        &self,
451        parent_scope: DIScope<'ctx>,
452        file: DIFile<'ctx>,
453        line: u32,
454        column: u32,
455    ) -> DILexicalBlock<'ctx> {
456        let metadata_ref = unsafe {
457            LLVMDIBuilderCreateLexicalBlock(
458                self.builder,
459                parent_scope.metadata_ref,
460                file.metadata_ref,
461                line as libc::c_uint,
462                column as libc::c_uint,
463            )
464        };
465        DILexicalBlock {
466            metadata_ref,
467            _marker: PhantomData,
468        }
469    }
470
471    /// Create a file scope.
472    pub fn create_file(&self, filename: &str, directory: &str) -> DIFile<'ctx> {
473        let metadata_ref = unsafe {
474            LLVMDIBuilderCreateFile(
475                self.builder,
476                filename.as_ptr() as _,
477                filename.len(),
478                directory.as_ptr() as _,
479                directory.len(),
480            )
481        };
482        DIFile {
483            metadata_ref,
484            _marker: PhantomData,
485        }
486    }
487
488    /// Create a debug location.
489    pub fn create_debug_location(
490        &self,
491        context: impl AsContextRef<'ctx>,
492        line: u32,
493        column: u32,
494        scope: DIScope<'ctx>,
495        inlined_at: Option<DILocation<'ctx>>,
496    ) -> DILocation<'ctx> {
497        let metadata_ref = unsafe {
498            LLVMDIBuilderCreateDebugLocation(
499                context.as_ctx_ref(),
500                line,
501                column,
502                scope.metadata_ref,
503                inlined_at.map(|l| l.metadata_ref).unwrap_or(std::ptr::null_mut()),
504            )
505        };
506        DILocation {
507            metadata_ref,
508            _marker: PhantomData,
509        }
510    }
511
512    /// Create a primitive basic type. `encoding` is an unsigned int flag (`DW_ATE_*`
513    /// enum) defined by the chosen DWARF standard.
514    #[llvm_versions(7..)]
515    pub fn create_basic_type(
516        &self,
517        name: &str,
518        size_in_bits: u64,
519        encoding: LLVMDWARFTypeEncoding,
520        #[cfg(not(feature = "llvm7-0"))] flags: DIFlags,
521    ) -> Result<DIBasicType<'ctx>, &'static str> {
522        if name.is_empty() {
523            // Also, LLVM returns the same type if you ask for the same
524            // (name, size_in_bits, encoding).
525            return Err("basic types must have names");
526        }
527        let metadata_ref = unsafe {
528            LLVMDIBuilderCreateBasicType(
529                self.builder,
530                name.as_ptr() as _,
531                name.len(),
532                size_in_bits,
533                encoding,
534                #[cfg(not(feature = "llvm7-0"))]
535                flags,
536            )
537        };
538        Ok(DIBasicType {
539            metadata_ref,
540            _marker: PhantomData,
541        })
542    }
543
544    /// Create a typedef (alias) of `ditype`
545    #[llvm_versions(8..)]
546    pub fn create_typedef(
547        &self,
548        ditype: DIType<'ctx>,
549        name: &str,
550        file: DIFile<'ctx>,
551        line_no: u32,
552        scope: DIScope<'ctx>,
553        #[cfg(not(any(feature = "llvm8-0", feature = "llvm9-0")))] align_in_bits: u32,
554    ) -> DIDerivedType<'ctx> {
555        let metadata_ref = unsafe {
556            LLVMDIBuilderCreateTypedef(
557                self.builder,
558                ditype.metadata_ref,
559                name.as_ptr() as _,
560                name.len(),
561                file.metadata_ref,
562                line_no,
563                scope.metadata_ref,
564                #[cfg(not(any(feature = "llvm8-0", feature = "llvm9-0")))]
565                align_in_bits,
566            )
567        };
568        DIDerivedType {
569            metadata_ref,
570            _marker: PhantomData,
571        }
572    }
573
574    /// Create union type of multiple types.
575    pub fn create_union_type(
576        &self,
577        scope: DIScope<'ctx>,
578        name: &str,
579        file: DIFile<'ctx>,
580        line_no: u32,
581        size_in_bits: u64,
582        align_in_bits: u32,
583        flags: DIFlags,
584        elements: &[DIType<'ctx>],
585        runtime_language: u32,
586        unique_id: &str,
587    ) -> DICompositeType<'ctx> {
588        let mut elements: Vec<LLVMMetadataRef> = elements.iter().map(|dt| dt.metadata_ref).collect();
589        let metadata_ref = unsafe {
590            LLVMDIBuilderCreateUnionType(
591                self.builder,
592                scope.metadata_ref,
593                name.as_ptr() as _,
594                name.len(),
595                file.metadata_ref,
596                line_no,
597                size_in_bits,
598                align_in_bits,
599                flags,
600                elements.as_mut_ptr(),
601                elements.len().try_into().unwrap(),
602                runtime_language,
603                unique_id.as_ptr() as _,
604                unique_id.len(),
605            )
606        };
607        DICompositeType {
608            metadata_ref,
609            _marker: PhantomData,
610        }
611    }
612
613    /// Create a type for a non-static member.
614    pub fn create_member_type(
615        &self,
616        scope: DIScope<'ctx>,
617        name: &str,
618        file: DIFile<'ctx>,
619        line_no: libc::c_uint,
620        size_in_bits: u64,
621        align_in_bits: u32,
622        offset_in_bits: u64,
623        flags: DIFlags,
624        ty: DIType<'ctx>,
625    ) -> DIDerivedType<'ctx> {
626        let metadata_ref = unsafe {
627            LLVMDIBuilderCreateMemberType(
628                self.builder,
629                scope.metadata_ref,
630                name.as_ptr() as _,
631                name.len(),
632                file.metadata_ref,
633                line_no,
634                size_in_bits,
635                align_in_bits,
636                offset_in_bits,
637                flags,
638                ty.metadata_ref,
639            )
640        };
641        DIDerivedType {
642            metadata_ref,
643            _marker: PhantomData,
644        }
645    }
646
647    /// Create a struct type.
648    pub fn create_struct_type(
649        &self,
650        scope: DIScope<'ctx>,
651        name: &str,
652        file: DIFile<'ctx>,
653        line_no: libc::c_uint,
654        size_in_bits: u64,
655        align_in_bits: u32,
656        flags: DIFlags,
657        derived_from: Option<DIType<'ctx>>,
658        elements: &[DIType<'ctx>],
659        runtime_language: libc::c_uint,
660        vtable_holder: Option<DIType<'ctx>>,
661        unique_id: &str,
662    ) -> DICompositeType<'ctx> {
663        let mut elements: Vec<LLVMMetadataRef> = elements.iter().map(|dt| dt.metadata_ref).collect();
664        let derived_from = derived_from.map_or(std::ptr::null_mut(), |dt| dt.metadata_ref);
665        let vtable_holder = vtable_holder.map_or(std::ptr::null_mut(), |dt| dt.metadata_ref);
666        let metadata_ref = unsafe {
667            LLVMDIBuilderCreateStructType(
668                self.builder,
669                scope.metadata_ref,
670                name.as_ptr() as _,
671                name.len(),
672                file.metadata_ref,
673                line_no,
674                size_in_bits,
675                align_in_bits,
676                flags,
677                derived_from,
678                elements.as_mut_ptr(),
679                elements.len().try_into().unwrap(),
680                runtime_language,
681                vtable_holder,
682                unique_id.as_ptr() as _,
683                unique_id.len(),
684            )
685        };
686        DICompositeType {
687            metadata_ref,
688            _marker: PhantomData,
689        }
690    }
691
692    /// Create a function type
693    pub fn create_subroutine_type(
694        &self,
695        file: DIFile<'ctx>,
696        return_type: Option<DIType<'ctx>>,
697        parameter_types: &[DIType<'ctx>],
698        flags: DIFlags,
699    ) -> DISubroutineType<'ctx> {
700        let mut p = vec![return_type.map_or(std::ptr::null_mut(), |t| t.metadata_ref)];
701        p.append(
702            &mut parameter_types
703                .iter()
704                .map(|t| t.metadata_ref)
705                .collect::<Vec<LLVMMetadataRef>>(),
706        );
707        let metadata_ref = unsafe {
708            LLVMDIBuilderCreateSubroutineType(
709                self.builder,
710                file.metadata_ref,
711                p.as_mut_ptr(),
712                p.len().try_into().unwrap(),
713                flags,
714            )
715        };
716        DISubroutineType {
717            metadata_ref,
718            _marker: PhantomData,
719        }
720    }
721
722    /// Creates a pointer type
723    pub fn create_pointer_type(
724        &self,
725        name: &str,
726        pointee: DIType<'ctx>,
727        size_in_bits: u64,
728        align_in_bits: u32,
729        address_space: AddressSpace,
730    ) -> DIDerivedType<'ctx> {
731        let metadata_ref = unsafe {
732            LLVMDIBuilderCreatePointerType(
733                self.builder,
734                pointee.metadata_ref,
735                size_in_bits,
736                align_in_bits,
737                address_space.0,
738                name.as_ptr() as _,
739                name.len(),
740            )
741        };
742
743        DIDerivedType {
744            metadata_ref,
745            _marker: PhantomData,
746        }
747    }
748
749    /// Creates a pointer type
750    pub fn create_reference_type(&self, pointee: DIType<'ctx>, tag: u32) -> DIDerivedType<'ctx> {
751        let metadata_ref = unsafe { LLVMDIBuilderCreateReferenceType(self.builder, tag, pointee.metadata_ref) };
752
753        DIDerivedType {
754            metadata_ref,
755            _marker: PhantomData,
756        }
757    }
758
759    /// Creates an array type
760    pub fn create_array_type(
761        &self,
762        inner_type: DIType<'ctx>,
763        size_in_bits: u64,
764        align_in_bits: u32,
765        subscripts: &[Range<i64>],
766    ) -> DICompositeType<'ctx> {
767        //Create subranges
768        let mut subscripts = subscripts
769            .iter()
770            .map(|range| {
771                let lower = range.start;
772                let upper = range.end;
773                let subscript_size = upper - lower;
774                unsafe { LLVMDIBuilderGetOrCreateSubrange(self.builder, lower, subscript_size) }
775            })
776            .collect::<Vec<_>>();
777        let metadata_ref = unsafe {
778            LLVMDIBuilderCreateArrayType(
779                self.builder,
780                size_in_bits,
781                align_in_bits,
782                inner_type.metadata_ref,
783                subscripts.as_mut_ptr(),
784                subscripts.len().try_into().unwrap(),
785            )
786        };
787
788        DICompositeType {
789            metadata_ref,
790            _marker: PhantomData,
791        }
792    }
793
794    #[llvm_versions(8..)]
795    pub fn create_global_variable_expression(
796        &self,
797        scope: DIScope<'ctx>,
798        name: &str,
799        linkage: &str,
800        file: DIFile<'ctx>,
801        line_no: u32,
802        ty: DIType<'ctx>,
803        local_to_unit: bool,
804        expression: Option<DIExpression>,
805        declaration: Option<DIScope>,
806        align_in_bits: u32,
807    ) -> DIGlobalVariableExpression<'ctx> {
808        let expression_ptr = expression.map_or(std::ptr::null_mut(), |dt| dt.metadata_ref);
809        let decl_ptr = declaration.map_or(std::ptr::null_mut(), |dt| dt.metadata_ref);
810        let metadata_ref = unsafe {
811            LLVMDIBuilderCreateGlobalVariableExpression(
812                self.builder,
813                scope.metadata_ref,
814                name.as_ptr() as _,
815                name.len(),
816                linkage.as_ptr() as _,
817                linkage.len(),
818                file.metadata_ref,
819                line_no,
820                ty.metadata_ref,
821                local_to_unit as _,
822                expression_ptr,
823                decl_ptr,
824                align_in_bits,
825            )
826        };
827        DIGlobalVariableExpression {
828            metadata_ref,
829            _marker: PhantomData,
830        }
831    }
832
833    #[llvm_versions(8..)]
834    pub fn create_constant_expression(&self, value: i64) -> DIExpression<'ctx> {
835        let metadata_ref = unsafe { LLVMDIBuilderCreateConstantValueExpression(self.builder, value as _) };
836
837        DIExpression {
838            metadata_ref,
839            _marker: PhantomData,
840        }
841    }
842
843    /// Create function parameter variable.
844    pub fn create_parameter_variable(
845        &self,
846        scope: DIScope<'ctx>,
847        name: &str,
848        arg_no: u32,
849        file: DIFile<'ctx>,
850        line_no: u32,
851        ty: DIType<'ctx>,
852        always_preserve: bool,
853        flags: DIFlags,
854    ) -> DILocalVariable<'ctx> {
855        let metadata_ref = unsafe {
856            LLVMDIBuilderCreateParameterVariable(
857                self.builder,
858                scope.metadata_ref,
859                name.as_ptr() as _,
860                name.len(),
861                arg_no,
862                file.metadata_ref,
863                line_no,
864                ty.metadata_ref,
865                always_preserve as _,
866                flags,
867            )
868        };
869        DILocalVariable {
870            metadata_ref,
871            _marker: PhantomData,
872        }
873    }
874
875    /// Create local automatic storage variable.
876    pub fn create_auto_variable(
877        &self,
878        scope: DIScope<'ctx>,
879        name: &str,
880        file: DIFile<'ctx>,
881        line_no: u32,
882        ty: DIType<'ctx>,
883        always_preserve: bool,
884        flags: DIFlags,
885        align_in_bits: u32,
886    ) -> DILocalVariable<'ctx> {
887        let metadata_ref = unsafe {
888            LLVMDIBuilderCreateAutoVariable(
889                self.builder,
890                scope.metadata_ref,
891                name.as_ptr() as _,
892                name.len(),
893                file.metadata_ref,
894                line_no,
895                ty.metadata_ref,
896                always_preserve as _,
897                flags,
898                align_in_bits,
899            )
900        };
901        DILocalVariable {
902            metadata_ref,
903            _marker: PhantomData,
904        }
905    }
906
907    pub fn create_namespace(&self, scope: DIScope<'ctx>, name: &str, export_symbols: bool) -> DINamespace<'ctx> {
908        let metadata_ref = unsafe {
909            LLVMDIBuilderCreateNameSpace(
910                self.builder,
911                scope.metadata_ref,
912                name.as_ptr() as _,
913                name.len(),
914                export_symbols as _,
915            )
916        };
917        DINamespace {
918            metadata_ref,
919            _marker: PhantomData,
920        }
921    }
922
923    /// Insert a variable declaration (`llvm.dbg.declare`) before a specified instruction.
924    pub fn insert_declare_before_instruction(
925        &self,
926        storage: PointerValue<'ctx>,
927        var_info: Option<DILocalVariable<'ctx>>,
928        expr: Option<DIExpression<'ctx>>,
929        debug_loc: DILocation<'ctx>,
930        instruction: InstructionValue<'ctx>,
931    ) -> InstructionValue<'ctx> {
932        let value_ref = unsafe {
933            LLVMDIBuilderInsertDeclareBefore(
934                self.builder,
935                storage.as_value_ref(),
936                var_info.map(|v| v.metadata_ref).unwrap_or(std::ptr::null_mut()),
937                expr.unwrap_or_else(|| self.create_expression(vec![])).metadata_ref,
938                debug_loc.metadata_ref,
939                instruction.as_value_ref(),
940            )
941        };
942
943        unsafe { InstructionValue::new(value_ref) }
944    }
945
946    /// Insert a variable declaration (`llvm.dbg.declare` intrinsic) at the end of `block`
947    pub fn insert_declare_at_end(
948        &self,
949        storage: PointerValue<'ctx>,
950        var_info: Option<DILocalVariable<'ctx>>,
951        expr: Option<DIExpression<'ctx>>,
952        debug_loc: DILocation<'ctx>,
953        block: BasicBlock<'ctx>,
954    ) -> InstructionValue<'ctx> {
955        let value_ref = unsafe {
956            LLVMDIBuilderInsertDeclareAtEnd(
957                self.builder,
958                storage.as_value_ref(),
959                var_info.map(|v| v.metadata_ref).unwrap_or(std::ptr::null_mut()),
960                expr.unwrap_or_else(|| self.create_expression(vec![])).metadata_ref,
961                debug_loc.metadata_ref,
962                block.basic_block,
963            )
964        };
965
966        unsafe { InstructionValue::new(value_ref) }
967    }
968
969    /// Create an expression
970    pub fn create_expression(&self, mut address_operations: Vec<i64>) -> DIExpression<'ctx> {
971        let metadata_ref = unsafe {
972            LLVMDIBuilderCreateExpression(
973                self.builder,
974                address_operations.as_mut_ptr() as *mut _,
975                address_operations.len(),
976            )
977        };
978        DIExpression {
979            metadata_ref,
980            _marker: PhantomData,
981        }
982    }
983
984    /// Insert a new llvm.dbg.value intrinsic call before an instruction.
985    pub fn insert_dbg_value_before(
986        &self,
987        value: BasicValueEnum<'ctx>,
988        var_info: DILocalVariable<'ctx>,
989        expr: Option<DIExpression<'ctx>>,
990        debug_loc: DILocation<'ctx>,
991        instruction: InstructionValue<'ctx>,
992    ) -> InstructionValue<'ctx> {
993        let value_ref = unsafe {
994            LLVMDIBuilderInsertDbgValueBefore(
995                self.builder,
996                value.as_value_ref(),
997                var_info.metadata_ref,
998                expr.unwrap_or_else(|| self.create_expression(vec![])).metadata_ref,
999                debug_loc.metadata_ref,
1000                instruction.as_value_ref(),
1001            )
1002        };
1003
1004        unsafe { InstructionValue::new(value_ref) }
1005    }
1006
1007    /// Construct a placeholders derived type to be used when building debug info with circular references.
1008    ///
1009    /// All placeholders must be replaced before calling finalize().
1010    pub unsafe fn create_placeholder_derived_type(&self, context: impl AsContextRef<'ctx>) -> DIDerivedType<'ctx> {
1011        let metadata_ref = LLVMTemporaryMDNode(context.as_ctx_ref(), std::ptr::null_mut(), 0);
1012        DIDerivedType {
1013            metadata_ref,
1014            _marker: PhantomData,
1015        }
1016    }
1017
1018    /// Deletes a placeholder, replacing all uses of it with another derived type.
1019    ///
1020    /// # Safety:
1021    /// This and any other copies of this placeholder made by Copy or Clone
1022    /// become dangling pointers after calling this method.
1023    pub unsafe fn replace_placeholder_derived_type(
1024        &self,
1025        placeholder: DIDerivedType<'ctx>,
1026        other: DIDerivedType<'ctx>,
1027    ) {
1028        LLVMMetadataReplaceAllUsesWith(placeholder.metadata_ref, other.metadata_ref);
1029    }
1030
1031    /// Construct any deferred debug info descriptors. May generate invalid metadata if debug info
1032    /// is incomplete. Module/function verification can then fail.
1033    ///
1034    /// Call before any kind of code generation (including verification). Can be called more than once.
1035    pub fn finalize(&self) {
1036        unsafe { LLVMDIBuilderFinalize(self.builder) };
1037    }
1038}
1039
1040impl<'ctx> Drop for DebugInfoBuilder<'ctx> {
1041    fn drop(&mut self) {
1042        self.finalize();
1043        unsafe { LLVMDisposeDIBuilder(self.builder) }
1044    }
1045}
1046
1047/// Source file scope for debug info
1048#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1049pub struct DIFile<'ctx> {
1050    pub(crate) metadata_ref: LLVMMetadataRef,
1051    _marker: PhantomData<&'ctx Context>,
1052}
1053
1054impl<'ctx> AsDIScope<'ctx> for DIFile<'ctx> {
1055    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1056        DIScope {
1057            metadata_ref: self.metadata_ref,
1058            _marker: PhantomData,
1059        }
1060    }
1061}
1062
1063impl<'ctx> DIFile<'ctx> {
1064    /// Acquires the underlying raw pointer belonging to this `DIFile` type.
1065    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1066        self.metadata_ref
1067    }
1068}
1069
1070/// Compilation unit scope for debug info
1071#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1072pub struct DICompileUnit<'ctx> {
1073    file: DIFile<'ctx>,
1074    pub(crate) metadata_ref: LLVMMetadataRef,
1075    _marker: PhantomData<&'ctx Context>,
1076}
1077
1078impl<'ctx> DICompileUnit<'ctx> {
1079    pub fn get_file(&self) -> DIFile<'ctx> {
1080        self.file
1081    }
1082
1083    /// Acquires the underlying raw pointer belonging to this `DICompileUnit` type.
1084    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1085        self.metadata_ref
1086    }
1087}
1088
1089impl<'ctx> AsDIScope<'ctx> for DICompileUnit<'ctx> {
1090    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1091        DIScope {
1092            metadata_ref: self.metadata_ref,
1093            _marker: PhantomData,
1094        }
1095    }
1096}
1097
1098/// Namespace scope for debug info
1099#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1100pub struct DINamespace<'ctx> {
1101    pub(crate) metadata_ref: LLVMMetadataRef,
1102    _marker: PhantomData<&'ctx Context>,
1103}
1104
1105impl<'ctx> DINamespace<'ctx> {
1106    /// Acquires the underlying raw pointer belonging to this `DINamespace` type.
1107    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1108        self.metadata_ref
1109    }
1110}
1111
1112impl<'ctx> AsDIScope<'ctx> for DINamespace<'ctx> {
1113    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1114        DIScope {
1115            metadata_ref: self.metadata_ref,
1116            _marker: PhantomData,
1117        }
1118    }
1119}
1120
1121/// Function body scope for debug info
1122#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1123pub struct DISubprogram<'ctx> {
1124    pub(crate) metadata_ref: LLVMMetadataRef,
1125    pub(crate) _marker: PhantomData<&'ctx Context>,
1126}
1127
1128impl<'ctx> AsDIScope<'ctx> for DISubprogram<'ctx> {
1129    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1130        DIScope {
1131            metadata_ref: self.metadata_ref,
1132            _marker: PhantomData,
1133        }
1134    }
1135}
1136
1137impl<'ctx> DISubprogram<'ctx> {
1138    /// Acquires the underlying raw pointer belonging to this `DISubprogram` type.
1139    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1140        self.metadata_ref
1141    }
1142}
1143
1144/// Any kind of debug info type
1145#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1146pub struct DIType<'ctx> {
1147    pub(crate) metadata_ref: LLVMMetadataRef,
1148    _marker: PhantomData<&'ctx Context>,
1149}
1150
1151impl<'ctx> DIType<'ctx> {
1152    pub fn get_size_in_bits(&self) -> u64 {
1153        unsafe { LLVMDITypeGetSizeInBits(self.metadata_ref) }
1154    }
1155
1156    pub fn get_align_in_bits(&self) -> u32 {
1157        unsafe { LLVMDITypeGetAlignInBits(self.metadata_ref) }
1158    }
1159
1160    pub fn get_offset_in_bits(&self) -> u64 {
1161        unsafe { LLVMDITypeGetOffsetInBits(self.metadata_ref) }
1162    }
1163
1164    /// Acquires the underlying raw pointer belonging to this `DIType` type.
1165    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1166        self.metadata_ref
1167    }
1168}
1169
1170impl<'ctx> AsDIScope<'ctx> for DIType<'ctx> {
1171    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1172        DIScope {
1173            metadata_ref: self.metadata_ref,
1174            _marker: PhantomData,
1175        }
1176    }
1177}
1178
1179/// A wrapper around a single type, such as a typedef or member type.
1180#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1181pub struct DIDerivedType<'ctx> {
1182    pub(crate) metadata_ref: LLVMMetadataRef,
1183    _marker: PhantomData<&'ctx Context>,
1184}
1185
1186impl<'ctx> DIDerivedType<'ctx> {
1187    pub fn as_type(&self) -> DIType<'ctx> {
1188        DIType {
1189            metadata_ref: self.metadata_ref,
1190            _marker: PhantomData,
1191        }
1192    }
1193}
1194
1195impl<'ctx> DIDerivedType<'ctx> {
1196    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1197        self.metadata_ref
1198    }
1199}
1200
1201impl<'ctx> AsDIScope<'ctx> for DIDerivedType<'ctx> {
1202    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1203        DIScope {
1204            metadata_ref: self.metadata_ref,
1205            _marker: PhantomData,
1206        }
1207    }
1208}
1209
1210/// A primitive debug info type created by `create_basic_type` method of `DebugInfoBuilder`
1211#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1212pub struct DIBasicType<'ctx> {
1213    pub(crate) metadata_ref: LLVMMetadataRef,
1214    _marker: PhantomData<&'ctx Context>,
1215}
1216
1217impl<'ctx> DIBasicType<'ctx> {
1218    pub fn as_type(&self) -> DIType<'ctx> {
1219        DIType {
1220            metadata_ref: self.metadata_ref,
1221            _marker: PhantomData,
1222        }
1223    }
1224
1225    /// Acquires the underlying raw pointer belonging to this `DIBasicType` type.
1226    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1227        self.metadata_ref
1228    }
1229}
1230
1231impl<'ctx> AsDIScope<'ctx> for DIBasicType<'ctx> {
1232    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1233        DIScope {
1234            metadata_ref: self.metadata_ref,
1235            _marker: PhantomData,
1236        }
1237    }
1238}
1239/// A wrapper around an array of types, such as a union or struct.
1240#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1241pub struct DICompositeType<'ctx> {
1242    pub(crate) metadata_ref: LLVMMetadataRef,
1243    _marker: PhantomData<&'ctx Context>,
1244}
1245
1246impl<'ctx> DICompositeType<'ctx> {
1247    pub fn as_type(&self) -> DIType<'ctx> {
1248        DIType {
1249            metadata_ref: self.metadata_ref,
1250            _marker: PhantomData,
1251        }
1252    }
1253
1254    /// Acquires the underlying raw pointer belonging to this `DICompositeType` type.
1255    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1256        self.metadata_ref
1257    }
1258}
1259
1260impl<'ctx> AsDIScope<'ctx> for DICompositeType<'ctx> {
1261    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1262        DIScope {
1263            metadata_ref: self.metadata_ref,
1264            _marker: PhantomData,
1265        }
1266    }
1267}
1268
1269/// Metadata representing the type of a function
1270#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1271pub struct DISubroutineType<'ctx> {
1272    pub(crate) metadata_ref: LLVMMetadataRef,
1273    _marker: PhantomData<&'ctx Context>,
1274}
1275
1276/// Lexical block scope for debug info
1277#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1278pub struct DILexicalBlock<'ctx> {
1279    pub(crate) metadata_ref: LLVMMetadataRef,
1280    _marker: PhantomData<&'ctx Context>,
1281}
1282
1283impl<'ctx> AsDIScope<'ctx> for DILexicalBlock<'ctx> {
1284    fn as_debug_info_scope(self) -> DIScope<'ctx> {
1285        DIScope {
1286            metadata_ref: self.metadata_ref,
1287            _marker: PhantomData,
1288        }
1289    }
1290}
1291
1292impl<'ctx> DILexicalBlock<'ctx> {
1293    /// Acquires the underlying raw pointer belonging to this `DILexicalBlock` type.
1294    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1295        self.metadata_ref
1296    }
1297}
1298
1299/// A debug location within the source code. Contains the following information:
1300///
1301/// - line, column
1302/// - scope
1303/// - inlined at
1304///
1305/// Created by `create_debug_location` of `DebugInfoBuilder` and consumed by
1306/// `set_current_debug_location` of `Builder`.
1307#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1308pub struct DILocation<'ctx> {
1309    pub(crate) metadata_ref: LLVMMetadataRef,
1310    pub(crate) _marker: PhantomData<&'ctx Context>,
1311}
1312
1313impl<'ctx> DILocation<'ctx> {
1314    pub fn get_line(&self) -> u32 {
1315        unsafe { LLVMDILocationGetLine(self.metadata_ref) }
1316    }
1317
1318    pub fn get_column(&self) -> u32 {
1319        unsafe { LLVMDILocationGetColumn(self.metadata_ref) }
1320    }
1321
1322    pub fn get_scope(&self) -> DIScope<'ctx> {
1323        DIScope {
1324            metadata_ref: unsafe { LLVMDILocationGetScope(self.metadata_ref) },
1325            _marker: PhantomData,
1326        }
1327    }
1328
1329    /// Acquires the underlying raw pointer belonging to this `DILocation` type.
1330    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1331        self.metadata_ref
1332    }
1333}
1334
1335/// Metadata representing a variable inside a scope
1336#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1337pub struct DILocalVariable<'ctx> {
1338    pub(crate) metadata_ref: LLVMMetadataRef,
1339    _marker: PhantomData<&'ctx Context>,
1340}
1341
1342impl<'ctx> DILocalVariable<'ctx> {
1343    /// Acquires the underlying raw pointer belonging to this `DILocalVariable` type.
1344    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1345        self.metadata_ref
1346    }
1347}
1348
1349#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1350pub struct DIGlobalVariableExpression<'ctx> {
1351    pub(crate) metadata_ref: LLVMMetadataRef,
1352    _marker: PhantomData<&'ctx Context>,
1353}
1354
1355impl<'ctx> DIGlobalVariableExpression<'ctx> {
1356    pub fn as_metadata_value(&self, context: impl AsContextRef<'ctx>) -> MetadataValue<'ctx> {
1357        unsafe { MetadataValue::new(LLVMMetadataAsValue(context.as_ctx_ref(), self.metadata_ref)) }
1358    }
1359
1360    /// Acquires the underlying raw pointer belonging to this `DIGlobalVariableExpression` type.
1361    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1362        self.metadata_ref
1363    }
1364}
1365
1366/// Specialized metadata node that contains a DWARF-like expression.
1367///
1368/// # Remarks
1369///
1370/// See also the [LLVM language reference](https://llvm.org/docs/LangRef.html#diexpression).
1371#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1372pub struct DIExpression<'ctx> {
1373    pub(crate) metadata_ref: LLVMMetadataRef,
1374    _marker: PhantomData<&'ctx Context>,
1375}
1376
1377impl<'ctx> DIExpression<'ctx> {
1378    /// Acquires the underlying raw pointer belonging to this `DIExpression` type.
1379    pub fn as_mut_ptr(&self) -> LLVMMetadataRef {
1380        self.metadata_ref
1381    }
1382}
1383
1384pub use flags::*;
1385mod flags {
1386    pub use llvm_sys::debuginfo::LLVMDIFlags as DIFlags;
1387    use llvm_sys::debuginfo::{LLVMDWARFEmissionKind, LLVMDWARFSourceLanguage};
1388
1389    pub trait DIFlagsConstants {
1390        const ZERO: Self;
1391        const PRIVATE: Self;
1392        const PROTECTED: Self;
1393        const PUBLIC: Self;
1394        const FWD_DECL: Self;
1395        const APPLE_BLOCK: Self;
1396        //#[llvm_versions(7..=9)]
1397        //const BLOCK_BYREF_STRUCT: Self;
1398        const VIRTUAL: Self;
1399        const ARTIFICIAL: Self;
1400        const EXPLICIT: Self;
1401        const PROTOTYPED: Self;
1402        const OBJC_CLASS_COMPLETE: Self;
1403        const OBJECT_POINTER: Self;
1404        const VECTOR: Self;
1405        const STATIC_MEMBER: Self;
1406        const LVALUE_REFERENCE: Self;
1407        const RVALUE_REFERENCE: Self;
1408        const RESERVED: Self;
1409        const SINGLE_INHERITANCE: Self;
1410        const MULTIPLE_INHERITANCE: Self;
1411        const VIRTUAL_INHERITANCE: Self;
1412        const INTRODUCED_VIRTUAL: Self;
1413        const BIT_FIELD: Self;
1414        const NO_RETURN: Self;
1415        //#[llvm_versions(7..=8)]
1416        //const MAIN_SUBPROGRAM: Self;
1417        const TYPE_PASS_BY_VALUE: Self;
1418        const TYPE_PASS_BY_REFERENCE: Self;
1419        //#[llvm_versions(7)]
1420        //const FIXED_ENUM: Self;
1421        //#[llvm_versions(8..)]
1422        //const ENUM_CLASS: Self;
1423        const THUNK: Self;
1424        //#[llvm_versions(7..=8)]
1425        //const TRIVIAL: Self;
1426        //#[llvm_versions(9..)]
1427        //const NON_TRIVIAL: Self;
1428        //#[llvm_versions(10)]
1429        //const RESERVED_BIT4: Self;
1430        //#[llvm_versions(8..)]
1431        //const BIGE_NDIAN: Self;
1432        //#[llvm_versions(8..)]
1433        //const LITTLE_ENDIAN: Self;
1434        const INDIRECT_VIRTUAL_BASE: Self;
1435    }
1436    impl DIFlagsConstants for DIFlags {
1437        const ZERO: DIFlags = llvm_sys::debuginfo::LLVMDIFlagZero;
1438        const PRIVATE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagPrivate;
1439        const PROTECTED: DIFlags = llvm_sys::debuginfo::LLVMDIFlagProtected;
1440        const PUBLIC: DIFlags = llvm_sys::debuginfo::LLVMDIFlagPublic;
1441        const FWD_DECL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagFwdDecl;
1442        const APPLE_BLOCK: DIFlags = llvm_sys::debuginfo::LLVMDIFlagAppleBlock;
1443        //#[llvm_versions(7..=9)]
1444        //const BLOCK_BYREF_STRUCT: DIFlags = llvm_sys::debuginfo::LLVMDIFlagBlockByrefStruct;
1445        const VIRTUAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagVirtual;
1446        const ARTIFICIAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagArtificial;
1447        const EXPLICIT: DIFlags = llvm_sys::debuginfo::LLVMDIFlagExplicit;
1448        const PROTOTYPED: DIFlags = llvm_sys::debuginfo::LLVMDIFlagPrototyped;
1449        const OBJC_CLASS_COMPLETE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagObjcClassComplete;
1450        const OBJECT_POINTER: DIFlags = llvm_sys::debuginfo::LLVMDIFlagObjectPointer;
1451        const VECTOR: DIFlags = llvm_sys::debuginfo::LLVMDIFlagVector;
1452        const STATIC_MEMBER: DIFlags = llvm_sys::debuginfo::LLVMDIFlagStaticMember;
1453        const LVALUE_REFERENCE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagLValueReference;
1454        const RVALUE_REFERENCE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagRValueReference;
1455        const RESERVED: DIFlags = llvm_sys::debuginfo::LLVMDIFlagReserved;
1456        const SINGLE_INHERITANCE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagSingleInheritance;
1457        const MULTIPLE_INHERITANCE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagMultipleInheritance;
1458        const VIRTUAL_INHERITANCE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagVirtualInheritance;
1459        const INTRODUCED_VIRTUAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagIntroducedVirtual;
1460        const BIT_FIELD: DIFlags = llvm_sys::debuginfo::LLVMDIFlagBitField;
1461        const NO_RETURN: DIFlags = llvm_sys::debuginfo::LLVMDIFlagNoReturn;
1462        //#[llvm_versions(7..=8)]
1463        //const MAIN_SUBPROGRAM: DIFlags = llvm_sys::debuginfo::LLVMDIFlagMainSubprogram;
1464        const TYPE_PASS_BY_VALUE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagTypePassByValue;
1465        const TYPE_PASS_BY_REFERENCE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagTypePassByReference;
1466        //#[llvm_versions(7)]
1467        //const FIXED_ENUM: DIFlags = llvm_sys::debuginfo::LLVMDIFlagFixedEnum;
1468        //#[llvm_versions(8..)]
1469        //const ENUM_CLASS: DIFlags = llvm_sys::debuginfo::LLVMDIFlagEnumClass;
1470        const THUNK: DIFlags = llvm_sys::debuginfo::LLVMDIFlagThunk;
1471        //#[llvm_versions(7..=8)]
1472        //const TRIVIAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagTrivial;
1473        //#[llvm_versions(9..)]
1474        //const NON_TRIVIAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagNonTrivial;
1475        //#[llvm_versions(10)]
1476        //const RESERVED_BIT4: DIFlags = llvm_sys::debuginfo::LLVMDIFlagReservedBit4;
1477        //#[llvm_versions(8..)]
1478        //const BIG_ENDIAN: DIFlags = llvm_sys::debuginfo::LLVMDIFlagBigEndian;
1479        //#[llvm_versions(8..)]
1480        //const LITTLE_ENDIAN: DIFlags = llvm_sys::debuginfo::LLVMDIFlagLittleEndian;
1481        const INDIRECT_VIRTUAL_BASE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagIndirectVirtualBase;
1482    }
1483
1484    /// The amount of debug information to emit. Corresponds to `LLVMDWARFEmissionKind` enum from LLVM.
1485    #[llvm_enum(LLVMDWARFEmissionKind)]
1486    #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1487    pub enum DWARFEmissionKind {
1488        #[llvm_variant(LLVMDWARFEmissionKindNone)]
1489        None,
1490        #[llvm_variant(LLVMDWARFEmissionKindFull)]
1491        Full,
1492        #[llvm_variant(LLVMDWARFEmissionKindLineTablesOnly)]
1493        LineTablesOnly,
1494    }
1495
1496    /// Source languages known by DWARF. Corresponds to `LLVMDWARFSourceLanguage` enum from LLVM.
1497    #[llvm_enum(LLVMDWARFSourceLanguage)]
1498    #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1499    pub enum DWARFSourceLanguage {
1500        #[llvm_variant(LLVMDWARFSourceLanguageC89)]
1501        C89,
1502        #[llvm_variant(LLVMDWARFSourceLanguageC)]
1503        C,
1504        #[llvm_variant(LLVMDWARFSourceLanguageAda83)]
1505        Ada83,
1506        #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus)]
1507        CPlusPlus,
1508        #[llvm_variant(LLVMDWARFSourceLanguageCobol74)]
1509        Cobol74,
1510        #[llvm_variant(LLVMDWARFSourceLanguageCobol85)]
1511        Cobol85,
1512        #[llvm_variant(LLVMDWARFSourceLanguageFortran77)]
1513        Fortran77,
1514        #[llvm_variant(LLVMDWARFSourceLanguageFortran90)]
1515        Fortran90,
1516        #[llvm_variant(LLVMDWARFSourceLanguagePascal83)]
1517        Pascal83,
1518        #[llvm_variant(LLVMDWARFSourceLanguageModula2)]
1519        Modula2,
1520        #[llvm_variant(LLVMDWARFSourceLanguageJava)]
1521        Java,
1522        #[llvm_variant(LLVMDWARFSourceLanguageC99)]
1523        C99,
1524        #[llvm_variant(LLVMDWARFSourceLanguageAda95)]
1525        Ada95,
1526        #[llvm_variant(LLVMDWARFSourceLanguageFortran95)]
1527        Fortran95,
1528        #[llvm_variant(LLVMDWARFSourceLanguagePLI)]
1529        PLI,
1530        #[llvm_variant(LLVMDWARFSourceLanguageObjC)]
1531        ObjC,
1532        #[llvm_variant(LLVMDWARFSourceLanguageObjC_plus_plus)]
1533        ObjCPlusPlus,
1534        #[llvm_variant(LLVMDWARFSourceLanguageUPC)]
1535        UPC,
1536        #[llvm_variant(LLVMDWARFSourceLanguageD)]
1537        D,
1538        #[llvm_variant(LLVMDWARFSourceLanguagePython)]
1539        Python,
1540        #[llvm_variant(LLVMDWARFSourceLanguageOpenCL)]
1541        OpenCL,
1542        #[llvm_variant(LLVMDWARFSourceLanguageGo)]
1543        Go,
1544        #[llvm_variant(LLVMDWARFSourceLanguageModula3)]
1545        Modula3,
1546        #[llvm_variant(LLVMDWARFSourceLanguageHaskell)]
1547        Haskell,
1548        #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus_03)]
1549        CPlusPlus03,
1550        #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus_11)]
1551        CPlusPlus11,
1552        #[llvm_variant(LLVMDWARFSourceLanguageOCaml)]
1553        OCaml,
1554        #[llvm_variant(LLVMDWARFSourceLanguageRust)]
1555        Rust,
1556        #[llvm_variant(LLVMDWARFSourceLanguageC11)]
1557        C11,
1558        #[llvm_variant(LLVMDWARFSourceLanguageSwift)]
1559        Swift,
1560        #[llvm_variant(LLVMDWARFSourceLanguageJulia)]
1561        Julia,
1562        #[llvm_variant(LLVMDWARFSourceLanguageDylan)]
1563        Dylan,
1564        #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus_14)]
1565        CPlusPlus14,
1566        #[llvm_variant(LLVMDWARFSourceLanguageFortran03)]
1567        Fortran03,
1568        #[llvm_variant(LLVMDWARFSourceLanguageFortran08)]
1569        Fortran08,
1570        #[llvm_variant(LLVMDWARFSourceLanguageRenderScript)]
1571        RenderScript,
1572        #[llvm_variant(LLVMDWARFSourceLanguageBLISS)]
1573        BLISS,
1574        #[llvm_variant(LLVMDWARFSourceLanguageMips_Assembler)]
1575        MipsAssembler,
1576        #[llvm_variant(LLVMDWARFSourceLanguageGOOGLE_RenderScript)]
1577        GOOGLERenderScript,
1578        #[llvm_variant(LLVMDWARFSourceLanguageBORLAND_Delphi)]
1579        BORLANDDelphi,
1580        #[llvm_versions(16..)]
1581        #[llvm_variant(LLVMDWARFSourceLanguageKotlin)]
1582        Kotlin,
1583        #[llvm_versions(16..)]
1584        #[llvm_variant(LLVMDWARFSourceLanguageZig)]
1585        Zig,
1586        #[llvm_versions(16..)]
1587        #[llvm_variant(LLVMDWARFSourceLanguageCrystal)]
1588        Crystal,
1589        #[llvm_versions(16..)]
1590        #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus_17)]
1591        CPlusPlus17,
1592        #[llvm_versions(16..)]
1593        #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus_20)]
1594        CPlusPlus20,
1595        #[llvm_versions(16..)]
1596        #[llvm_variant(LLVMDWARFSourceLanguageC17)]
1597        C17,
1598        #[llvm_versions(16..)]
1599        #[llvm_variant(LLVMDWARFSourceLanguageFortran18)]
1600        Fortran18,
1601        #[llvm_versions(16..)]
1602        #[llvm_variant(LLVMDWARFSourceLanguageAda2005)]
1603        Ada2005,
1604        #[llvm_versions(16..)]
1605        #[llvm_variant(LLVMDWARFSourceLanguageAda2012)]
1606        Ada2012,
1607        #[llvm_versions(17..)]
1608        #[llvm_variant(LLVMDWARFSourceLanguageMojo)]
1609        Mojo,
1610    }
1611}