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