Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/inkwell-0.1.1/src/targets.rs
Line
Count
Source (jump to first uncovered line)
1
use llvm_sys::target::{
2
    LLVMABIAlignmentOfType, LLVMABISizeOfType, LLVMByteOrder, LLVMByteOrdering, LLVMCallFrameAlignmentOfType,
3
    LLVMCopyStringRepOfTargetData, LLVMCreateTargetData, LLVMDisposeTargetData, LLVMElementAtOffset,
4
    LLVMIntPtrTypeForASInContext, LLVMIntPtrTypeInContext, LLVMOffsetOfElement, LLVMPointerSize, LLVMPointerSizeForAS,
5
    LLVMPreferredAlignmentOfGlobal, LLVMPreferredAlignmentOfType, LLVMSizeOfTypeInBits, LLVMStoreSizeOfType,
6
    LLVMTargetDataRef,
7
};
8
#[llvm_versions(4.0..=latest)]
9
use llvm_sys::target_machine::LLVMCreateTargetDataLayout;
10
use llvm_sys::target_machine::{
11
    LLVMAddAnalysisPasses, LLVMCodeGenFileType, LLVMCodeGenOptLevel, LLVMCodeModel, LLVMCreateTargetMachine,
12
    LLVMDisposeTargetMachine, LLVMGetDefaultTargetTriple, LLVMGetFirstTarget, LLVMGetNextTarget,
13
    LLVMGetTargetDescription, LLVMGetTargetFromName, LLVMGetTargetFromTriple, LLVMGetTargetMachineCPU,
14
    LLVMGetTargetMachineFeatureString, LLVMGetTargetMachineTarget, LLVMGetTargetMachineTriple, LLVMGetTargetName,
15
    LLVMRelocMode, LLVMSetTargetMachineAsmVerbosity, LLVMTargetHasAsmBackend, LLVMTargetHasJIT,
16
    LLVMTargetHasTargetMachine, LLVMTargetMachineEmitToFile, LLVMTargetMachineEmitToMemoryBuffer, LLVMTargetMachineRef,
17
    LLVMTargetRef,
18
};
19
use once_cell::sync::Lazy;
20
use parking_lot::RwLock;
21
22
use crate::context::AsContextRef;
23
use crate::data_layout::DataLayout;
24
use crate::memory_buffer::MemoryBuffer;
25
use crate::module::Module;
26
use crate::passes::PassManager;
27
use crate::support::{to_c_str, LLVMString};
28
use crate::types::{AnyType, AsTypeRef, IntType, StructType};
29
use crate::values::{AsValueRef, GlobalValue};
30
use crate::{AddressSpace, OptimizationLevel};
31
32
use std::default::Default;
33
use std::ffi::CStr;
34
use std::fmt;
35
use std::mem::MaybeUninit;
36
use std::path::Path;
37
use std::ptr;
38
39
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
40
pub enum CodeModel {
41
    Default,
42
    JITDefault,
43
    Small,
44
    Kernel,
45
    Medium,
46
    Large,
47
}
48
49
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
50
pub enum RelocMode {
51
    Default,
52
    Static,
53
    PIC,
54
    DynamicNoPic,
55
}
56
57
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
58
pub enum FileType {
59
    Assembly,
60
    Object,
61
}
62
63
impl FileType {
64
159k
    fn as_llvm_file_type(&self) -> LLVMCodeGenFileType {
65
159k
        match *self {
66
0
            FileType::Assembly => LLVMCodeGenFileType::LLVMAssemblyFile,
67
159k
            FileType::Object => LLVMCodeGenFileType::LLVMObjectFile,
68
        }
69
159k
    }
70
}
71
72
// TODO: Doc: Base gets you TargetMachine support, machine_code gets you asm_backend
73
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
74
pub struct InitializationConfig {
75
    pub asm_parser: bool,
76
    pub asm_printer: bool,
77
    pub base: bool,
78
    pub disassembler: bool,
79
    pub info: bool,
80
    pub machine_code: bool,
81
}
82
83
impl Default for InitializationConfig {
84
0
    fn default() -> Self {
85
0
        InitializationConfig {
86
0
            asm_parser: true,
87
0
            asm_printer: true,
88
0
            base: true,
89
0
            disassembler: true,
90
0
            info: true,
91
0
            machine_code: true,
92
0
        }
93
0
    }
94
}
95
96
#[derive(Eq)]
97
pub struct TargetTriple {
98
    pub(crate) triple: LLVMString,
99
}
100
101
impl TargetTriple {
102
331k
    pub unsafe fn new(triple: LLVMString) -> TargetTriple {
103
331k
        TargetTriple { triple }
104
331k
    }
105
106
171k
    pub fn create(triple: &str) -> TargetTriple {
107
171k
        let c_string = to_c_str(triple);
108
171k
109
171k
        TargetTriple {
110
171k
            triple: LLVMString::create_from_c_str(&c_string),
111
171k
        }
112
171k
    }
113
114
171k
    pub fn as_str(&self) -> &CStr {
115
171k
        unsafe { CStr::from_ptr(self.as_ptr()) }
116
171k
    }
117
118
674k
    pub fn as_ptr(&self) -> *const ::libc::c_char {
119
674k
        self.triple.as_ptr()
120
674k
    }
121
}
122
123
impl PartialEq for TargetTriple {
124
0
    fn eq(&self, other: &TargetTriple) -> bool {
125
0
        self.triple == other.triple
126
0
    }
127
}
128
129
impl fmt::Debug for TargetTriple {
130
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131
0
        write!(f, "TargetTriple({:?})", self.triple)
132
0
    }
133
}
134
135
impl fmt::Display for TargetTriple {
136
0
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
137
0
        write!(f, "TargetTriple({:?})", self.triple)
138
0
    }
139
}
140
141
2
static TARGET_LOCK: Lazy<RwLock<()>> = Lazy::new(|| RwLock::new(()));
142
143
// NOTE: Versions verified as target-complete: 3.6, 3.7, 3.8, 3.9, 4.0
144
#[derive(Debug, Eq, PartialEq)]
145
pub struct Target {
146
    target: LLVMTargetRef,
147
}
148
149
impl Target {
150
171k
    pub unsafe fn new(target: LLVMTargetRef) -> Self {
151
171k
        assert!(!target.is_null());
152
153
171k
        Target { target }
154
171k
    }
155
156
    /// Acquires the underlying raw pointer belonging to this `Target` type.
157
0
    pub fn as_mut_ptr(&self) -> LLVMTargetRef {
158
0
        self.target
159
0
    }
160
161
    // REVIEW: Should this just initialize all? Is opt into each a good idea?
162
    #[cfg(feature = "target-x86")]
163
171k
    pub fn initialize_x86(config: &InitializationConfig) {
164
171k
        use llvm_sys::target::{
165
171k
            LLVMInitializeX86AsmParser, LLVMInitializeX86AsmPrinter, LLVMInitializeX86Disassembler,
166
171k
            LLVMInitializeX86Target, LLVMInitializeX86TargetInfo, LLVMInitializeX86TargetMC,
167
171k
        };
168
171k
169
171k
        if config.base {
170
171k
            let _guard = TARGET_LOCK.write();
171
171k
            unsafe { LLVMInitializeX86Target() };
172
171k
        }
173
174
171k
        if config.info {
175
171k
            let _guard = TARGET_LOCK.write();
176
171k
            unsafe { LLVMInitializeX86TargetInfo() };
177
171k
        }
178
179
171k
        if config.asm_printer {
180
171k
            let _guard = TARGET_LOCK.write();
181
171k
            unsafe { LLVMInitializeX86AsmPrinter() };
182
171k
        }
183
184
171k
        if config.asm_parser {
185
171k
            let _guard = TARGET_LOCK.write();
186
171k
            unsafe { LLVMInitializeX86AsmParser() };
187
171k
        }
188
189
171k
        if config.disassembler {
190
171k
            let _guard = TARGET_LOCK.write();
191
171k
            unsafe { LLVMInitializeX86Disassembler() };
192
171k
        }
193
194
171k
        if config.machine_code {
195
171k
            let _guard = TARGET_LOCK.write();
196
171k
            unsafe { LLVMInitializeX86TargetMC() };
197
171k
        }
198
171k
    }
199
200
    #[cfg(feature = "target-arm")]
201
    pub fn initialize_arm(config: &InitializationConfig) {
202
        use llvm_sys::target::{
203
            LLVMInitializeARMAsmParser, LLVMInitializeARMAsmPrinter, LLVMInitializeARMDisassembler,
204
            LLVMInitializeARMTarget, LLVMInitializeARMTargetInfo, LLVMInitializeARMTargetMC,
205
        };
206
207
        if config.base {
208
            let _guard = TARGET_LOCK.write();
209
            unsafe { LLVMInitializeARMTarget() };
210
        }
211
212
        if config.info {
213
            let _guard = TARGET_LOCK.write();
214
            unsafe { LLVMInitializeARMTargetInfo() };
215
        }
216
217
        if config.asm_printer {
218
            let _guard = TARGET_LOCK.write();
219
            unsafe { LLVMInitializeARMAsmPrinter() };
220
        }
221
222
        if config.asm_parser {
223
            let _guard = TARGET_LOCK.write();
224
            unsafe { LLVMInitializeARMAsmParser() };
225
        }
226
227
        if config.disassembler {
228
            let _guard = TARGET_LOCK.write();
229
            unsafe { LLVMInitializeARMDisassembler() };
230
        }
231
232
        if config.machine_code {
233
            let _guard = TARGET_LOCK.write();
234
            unsafe { LLVMInitializeARMTargetMC() };
235
        }
236
    }
237
238
    #[cfg(feature = "target-mips")]
239
    pub fn initialize_mips(config: &InitializationConfig) {
240
        use llvm_sys::target::{
241
            LLVMInitializeMipsAsmParser, LLVMInitializeMipsAsmPrinter, LLVMInitializeMipsDisassembler,
242
            LLVMInitializeMipsTarget, LLVMInitializeMipsTargetInfo, LLVMInitializeMipsTargetMC,
243
        };
244
245
        if config.base {
246
            let _guard = TARGET_LOCK.write();
247
            unsafe { LLVMInitializeMipsTarget() };
248
        }
249
250
        if config.info {
251
            let _guard = TARGET_LOCK.write();
252
            unsafe { LLVMInitializeMipsTargetInfo() };
253
        }
254
255
        if config.asm_printer {
256
            let _guard = TARGET_LOCK.write();
257
            unsafe { LLVMInitializeMipsAsmPrinter() };
258
        }
259
260
        if config.asm_parser {
261
            let _guard = TARGET_LOCK.write();
262
            unsafe { LLVMInitializeMipsAsmParser() };
263
        }
264
265
        if config.disassembler {
266
            let _guard = TARGET_LOCK.write();
267
            unsafe { LLVMInitializeMipsDisassembler() };
268
        }
269
270
        if config.machine_code {
271
            let _guard = TARGET_LOCK.write();
272
            unsafe { LLVMInitializeMipsTargetMC() };
273
        }
274
    }
275
276
    #[cfg(feature = "target-aarch64")]
277
0
    pub fn initialize_aarch64(config: &InitializationConfig) {
278
0
        use llvm_sys::target::{
279
0
            LLVMInitializeAArch64AsmParser, LLVMInitializeAArch64AsmPrinter, LLVMInitializeAArch64Disassembler,
280
0
            LLVMInitializeAArch64Target, LLVMInitializeAArch64TargetInfo, LLVMInitializeAArch64TargetMC,
281
0
        };
282
0
283
0
        if config.base {
284
0
            let _guard = TARGET_LOCK.write();
285
0
            unsafe { LLVMInitializeAArch64Target() };
286
0
        }
287
288
0
        if config.info {
289
0
            let _guard = TARGET_LOCK.write();
290
0
            unsafe { LLVMInitializeAArch64TargetInfo() };
291
0
        }
292
293
0
        if config.asm_printer {
294
0
            let _guard = TARGET_LOCK.write();
295
0
            unsafe { LLVMInitializeAArch64AsmPrinter() };
296
0
        }
297
298
0
        if config.asm_parser {
299
0
            let _guard = TARGET_LOCK.write();
300
0
            unsafe { LLVMInitializeAArch64AsmParser() };
301
0
        }
302
303
0
        if config.disassembler {
304
0
            let _guard = TARGET_LOCK.write();
305
0
            unsafe { LLVMInitializeAArch64Disassembler() };
306
0
        }
307
308
0
        if config.machine_code {
309
0
            let _guard = TARGET_LOCK.write();
310
0
            unsafe { LLVMInitializeAArch64TargetMC() };
311
0
        }
312
0
    }
313
314
    #[cfg(feature = "target-amdgpu")]
315
    #[llvm_versions(4.0..=latest)]
316
    pub fn initialize_amd_gpu(config: &InitializationConfig) {
317
        use llvm_sys::target::{
318
            LLVMInitializeAMDGPUAsmParser, LLVMInitializeAMDGPUAsmPrinter, LLVMInitializeAMDGPUTarget,
319
            LLVMInitializeAMDGPUTargetInfo, LLVMInitializeAMDGPUTargetMC,
320
        };
321
322
        if config.base {
323
            let _guard = TARGET_LOCK.write();
324
            unsafe { LLVMInitializeAMDGPUTarget() };
325
        }
326
327
        if config.info {
328
            let _guard = TARGET_LOCK.write();
329
            unsafe { LLVMInitializeAMDGPUTargetInfo() };
330
        }
331
332
        if config.asm_printer {
333
            let _guard = TARGET_LOCK.write();
334
            unsafe { LLVMInitializeAMDGPUAsmPrinter() };
335
        }
336
337
        if config.asm_parser {
338
            let _guard = TARGET_LOCK.write();
339
            unsafe { LLVMInitializeAMDGPUAsmParser() };
340
        }
341
342
        if config.machine_code {
343
            let _guard = TARGET_LOCK.write();
344
            unsafe { LLVMInitializeAMDGPUTargetMC() };
345
        }
346
347
        // Disassembler Status Unknown
348
    }
349
350
    #[cfg(feature = "target-systemz")]
351
    pub fn initialize_system_z(config: &InitializationConfig) {
352
        use llvm_sys::target::{
353
            LLVMInitializeSystemZAsmParser, LLVMInitializeSystemZAsmPrinter, LLVMInitializeSystemZDisassembler,
354
            LLVMInitializeSystemZTarget, LLVMInitializeSystemZTargetInfo, LLVMInitializeSystemZTargetMC,
355
        };
356
357
        if config.base {
358
            let _guard = TARGET_LOCK.write();
359
            unsafe { LLVMInitializeSystemZTarget() };
360
        }
361
362
        if config.info {
363
            let _guard = TARGET_LOCK.write();
364
            unsafe { LLVMInitializeSystemZTargetInfo() };
365
        }
366
367
        if config.asm_printer {
368
            let _guard = TARGET_LOCK.write();
369
            unsafe { LLVMInitializeSystemZAsmPrinter() };
370
        }
371
372
        if config.asm_parser {
373
            let _guard = TARGET_LOCK.write();
374
            unsafe { LLVMInitializeSystemZAsmParser() };
375
        }
376
377
        if config.disassembler {
378
            let _guard = TARGET_LOCK.write();
379
            unsafe { LLVMInitializeSystemZDisassembler() };
380
        }
381
382
        if config.machine_code {
383
            let _guard = TARGET_LOCK.write();
384
            unsafe { LLVMInitializeSystemZTargetMC() };
385
        }
386
    }
387
388
    #[cfg(feature = "target-hexagon")]
389
    pub fn initialize_hexagon(config: &InitializationConfig) {
390
        use llvm_sys::target::{
391
            LLVMInitializeHexagonAsmPrinter, LLVMInitializeHexagonDisassembler, LLVMInitializeHexagonTarget,
392
            LLVMInitializeHexagonTargetInfo, LLVMInitializeHexagonTargetMC,
393
        };
394
395
        if config.base {
396
            let _guard = TARGET_LOCK.write();
397
            unsafe { LLVMInitializeHexagonTarget() };
398
        }
399
400
        if config.info {
401
            let _guard = TARGET_LOCK.write();
402
            unsafe { LLVMInitializeHexagonTargetInfo() };
403
        }
404
405
        if config.asm_printer {
406
            let _guard = TARGET_LOCK.write();
407
            unsafe { LLVMInitializeHexagonAsmPrinter() };
408
        }
409
410
        // Asm parser status unknown
411
412
        if config.disassembler {
413
            let _guard = TARGET_LOCK.write();
414
            unsafe { LLVMInitializeHexagonDisassembler() };
415
        }
416
417
        if config.machine_code {
418
            let _guard = TARGET_LOCK.write();
419
            unsafe { LLVMInitializeHexagonTargetMC() };
420
        }
421
    }
422
423
    #[cfg(feature = "target-nvptx")]
424
    pub fn initialize_nvptx(config: &InitializationConfig) {
425
        use llvm_sys::target::{
426
            LLVMInitializeNVPTXAsmPrinter, LLVMInitializeNVPTXTarget, LLVMInitializeNVPTXTargetInfo,
427
            LLVMInitializeNVPTXTargetMC,
428
        };
429
430
        if config.base {
431
            let _guard = TARGET_LOCK.write();
432
            unsafe { LLVMInitializeNVPTXTarget() };
433
        }
434
435
        if config.info {
436
            let _guard = TARGET_LOCK.write();
437
            unsafe { LLVMInitializeNVPTXTargetInfo() };
438
        }
439
440
        if config.asm_printer {
441
            let _guard = TARGET_LOCK.write();
442
            unsafe { LLVMInitializeNVPTXAsmPrinter() };
443
        }
444
445
        // Asm parser status unknown
446
447
        if config.machine_code {
448
            let _guard = TARGET_LOCK.write();
449
            unsafe { LLVMInitializeNVPTXTargetMC() };
450
        }
451
452
        // Disassembler status unknown
453
    }
454
455
    #[cfg(feature = "target-msp430")]
456
    pub fn initialize_msp430(config: &InitializationConfig) {
457
        use llvm_sys::target::{
458
            LLVMInitializeMSP430AsmPrinter, LLVMInitializeMSP430Target, LLVMInitializeMSP430TargetInfo,
459
            LLVMInitializeMSP430TargetMC,
460
        };
461
462
        if config.base {
463
            let _guard = TARGET_LOCK.write();
464
            unsafe { LLVMInitializeMSP430Target() };
465
        }
466
467
        if config.info {
468
            let _guard = TARGET_LOCK.write();
469
            unsafe { LLVMInitializeMSP430TargetInfo() };
470
        }
471
472
        if config.asm_printer {
473
            let _guard = TARGET_LOCK.write();
474
            unsafe { LLVMInitializeMSP430AsmPrinter() };
475
        }
476
477
        // Asm parser status unknown
478
479
        if config.machine_code {
480
            let _guard = TARGET_LOCK.write();
481
            unsafe { LLVMInitializeMSP430TargetMC() };
482
        }
483
484
        // Disassembler status unknown
485
    }
486
487
    #[cfg(feature = "target-xcore")]
488
    pub fn initialize_x_core(config: &InitializationConfig) {
489
        use llvm_sys::target::{
490
            LLVMInitializeXCoreAsmPrinter, LLVMInitializeXCoreDisassembler, LLVMInitializeXCoreTarget,
491
            LLVMInitializeXCoreTargetInfo, LLVMInitializeXCoreTargetMC,
492
        };
493
494
        if config.base {
495
            let _guard = TARGET_LOCK.write();
496
            unsafe { LLVMInitializeXCoreTarget() };
497
        }
498
499
        if config.info {
500
            let _guard = TARGET_LOCK.write();
501
            unsafe { LLVMInitializeXCoreTargetInfo() };
502
        }
503
504
        if config.asm_printer {
505
            let _guard = TARGET_LOCK.write();
506
            unsafe { LLVMInitializeXCoreAsmPrinter() };
507
        }
508
509
        // Asm parser status unknown
510
511
        if config.disassembler {
512
            let _guard = TARGET_LOCK.write();
513
            unsafe { LLVMInitializeXCoreDisassembler() };
514
        }
515
516
        if config.machine_code {
517
            let _guard = TARGET_LOCK.write();
518
            unsafe { LLVMInitializeXCoreTargetMC() };
519
        }
520
    }
521
522
    #[cfg(feature = "target-powerpc")]
523
    pub fn initialize_power_pc(config: &InitializationConfig) {
524
        use llvm_sys::target::{
525
            LLVMInitializePowerPCAsmParser, LLVMInitializePowerPCAsmPrinter, LLVMInitializePowerPCDisassembler,
526
            LLVMInitializePowerPCTarget, LLVMInitializePowerPCTargetInfo, LLVMInitializePowerPCTargetMC,
527
        };
528
529
        if config.base {
530
            let _guard = TARGET_LOCK.write();
531
            unsafe { LLVMInitializePowerPCTarget() };
532
        }
533
534
        if config.info {
535
            let _guard = TARGET_LOCK.write();
536
            unsafe { LLVMInitializePowerPCTargetInfo() };
537
        }
538
539
        if config.asm_printer {
540
            let _guard = TARGET_LOCK.write();
541
            unsafe { LLVMInitializePowerPCAsmPrinter() };
542
        }
543
544
        if config.asm_parser {
545
            let _guard = TARGET_LOCK.write();
546
            unsafe { LLVMInitializePowerPCAsmParser() };
547
        }
548
549
        if config.disassembler {
550
            let _guard = TARGET_LOCK.write();
551
            unsafe { LLVMInitializePowerPCDisassembler() };
552
        }
553
554
        if config.machine_code {
555
            let _guard = TARGET_LOCK.write();
556
            unsafe { LLVMInitializePowerPCTargetMC() };
557
        }
558
    }
559
560
    #[cfg(feature = "target-sparc")]
561
    pub fn initialize_sparc(config: &InitializationConfig) {
562
        use llvm_sys::target::{
563
            LLVMInitializeSparcAsmParser, LLVMInitializeSparcAsmPrinter, LLVMInitializeSparcDisassembler,
564
            LLVMInitializeSparcTarget, LLVMInitializeSparcTargetInfo, LLVMInitializeSparcTargetMC,
565
        };
566
567
        if config.base {
568
            let _guard = TARGET_LOCK.write();
569
            unsafe { LLVMInitializeSparcTarget() };
570
        }
571
572
        if config.info {
573
            let _guard = TARGET_LOCK.write();
574
            unsafe { LLVMInitializeSparcTargetInfo() };
575
        }
576
577
        if config.asm_printer {
578
            let _guard = TARGET_LOCK.write();
579
            unsafe { LLVMInitializeSparcAsmPrinter() };
580
        }
581
582
        if config.asm_parser {
583
            let _guard = TARGET_LOCK.write();
584
            unsafe { LLVMInitializeSparcAsmParser() };
585
        }
586
587
        if config.disassembler {
588
            let _guard = TARGET_LOCK.write();
589
            unsafe { LLVMInitializeSparcDisassembler() };
590
        }
591
592
        if config.machine_code {
593
            let _guard = TARGET_LOCK.write();
594
            unsafe { LLVMInitializeSparcTargetMC() };
595
        }
596
    }
597
598
    #[cfg(feature = "target-bpf")]
599
    pub fn initialize_bpf(config: &InitializationConfig) {
600
        use llvm_sys::target::{
601
            LLVMInitializeBPFAsmPrinter, LLVMInitializeBPFTarget, LLVMInitializeBPFTargetInfo,
602
            LLVMInitializeBPFTargetMC,
603
        };
604
605
        if config.base {
606
            let _guard = TARGET_LOCK.write();
607
            unsafe { LLVMInitializeBPFTarget() };
608
        }
609
610
        if config.info {
611
            let _guard = TARGET_LOCK.write();
612
            unsafe { LLVMInitializeBPFTargetInfo() };
613
        }
614
615
        if config.asm_printer {
616
            let _guard = TARGET_LOCK.write();
617
            unsafe { LLVMInitializeBPFAsmPrinter() };
618
        }
619
620
        // No asm parser
621
622
        if config.disassembler {
623
            use llvm_sys::target::LLVMInitializeBPFDisassembler;
624
625
            let _guard = TARGET_LOCK.write();
626
            unsafe { LLVMInitializeBPFDisassembler() };
627
        }
628
629
        if config.machine_code {
630
            let _guard = TARGET_LOCK.write();
631
            unsafe { LLVMInitializeBPFTargetMC() };
632
        }
633
    }
634
635
    #[cfg(feature = "target-lanai")]
636
    #[llvm_versions(4.0..=latest)]
637
    pub fn initialize_lanai(config: &InitializationConfig) {
638
        use llvm_sys::target::{
639
            LLVMInitializeLanaiAsmParser, LLVMInitializeLanaiAsmPrinter, LLVMInitializeLanaiDisassembler,
640
            LLVMInitializeLanaiTarget, LLVMInitializeLanaiTargetInfo, LLVMInitializeLanaiTargetMC,
641
        };
642
643
        if config.base {
644
            let _guard = TARGET_LOCK.write();
645
            unsafe { LLVMInitializeLanaiTarget() };
646
        }
647
648
        if config.info {
649
            let _guard = TARGET_LOCK.write();
650
            unsafe { LLVMInitializeLanaiTargetInfo() };
651
        }
652
653
        if config.asm_printer {
654
            let _guard = TARGET_LOCK.write();
655
            unsafe { LLVMInitializeLanaiAsmPrinter() };
656
        }
657
658
        if config.asm_parser {
659
            let _guard = TARGET_LOCK.write();
660
            unsafe { LLVMInitializeLanaiAsmParser() };
661
        }
662
663
        if config.disassembler {
664
            let _guard = TARGET_LOCK.write();
665
            unsafe { LLVMInitializeLanaiDisassembler() };
666
        }
667
668
        if config.machine_code {
669
            let _guard = TARGET_LOCK.write();
670
            unsafe { LLVMInitializeLanaiTargetMC() };
671
        }
672
    }
673
674
    // RISCV was accidentally built by default in 4.0 since it was meant to be marked
675
    // experimental and so it was later removed from default builds in 5.0 until it was
676
    // officially released in 9.0 Since llvm-sys doesn't officially support any experimental
677
    // targets we're going to make this 9.0+ only. See
678
    // https://lists.llvm.org/pipermail/llvm-dev/2017-August/116347.html for more info.
679
    #[cfg(feature = "target-riscv")]
680
    #[llvm_versions(9.0..=latest)]
681
0
    pub fn initialize_riscv(config: &InitializationConfig) {
682
0
        use llvm_sys::target::{
683
0
            LLVMInitializeRISCVAsmParser, LLVMInitializeRISCVAsmPrinter, LLVMInitializeRISCVDisassembler,
684
0
            LLVMInitializeRISCVTarget, LLVMInitializeRISCVTargetInfo, LLVMInitializeRISCVTargetMC,
685
0
        };
686
0
687
0
        if config.base {
688
0
            let _guard = TARGET_LOCK.write();
689
0
            unsafe { LLVMInitializeRISCVTarget() };
690
0
        }
691
692
0
        if config.info {
693
0
            let _guard = TARGET_LOCK.write();
694
0
            unsafe { LLVMInitializeRISCVTargetInfo() };
695
0
        }
696
697
0
        if config.asm_printer {
698
0
            let _guard = TARGET_LOCK.write();
699
0
            unsafe { LLVMInitializeRISCVAsmPrinter() };
700
0
        }
701
702
0
        if config.asm_parser {
703
0
            let _guard = TARGET_LOCK.write();
704
0
            unsafe { LLVMInitializeRISCVAsmParser() };
705
0
        }
706
707
0
        if config.disassembler {
708
0
            let _guard = TARGET_LOCK.write();
709
0
            unsafe { LLVMInitializeRISCVDisassembler() };
710
0
        }
711
712
0
        if config.machine_code {
713
0
            let _guard = TARGET_LOCK.write();
714
0
            unsafe { LLVMInitializeRISCVTargetMC() };
715
0
        }
716
0
    }
717
718
    #[cfg(feature = "target-webassembly")]
719
    #[llvm_versions(8.0..=latest)]
720
    pub fn initialize_webassembly(config: &InitializationConfig) {
721
        use llvm_sys::target::{
722
            LLVMInitializeWebAssemblyAsmParser, LLVMInitializeWebAssemblyAsmPrinter,
723
            LLVMInitializeWebAssemblyDisassembler, LLVMInitializeWebAssemblyTarget,
724
            LLVMInitializeWebAssemblyTargetInfo, LLVMInitializeWebAssemblyTargetMC,
725
        };
726
727
        if config.base {
728
            let _guard = TARGET_LOCK.write();
729
            unsafe { LLVMInitializeWebAssemblyTarget() };
730
        }
731
732
        if config.info {
733
            let _guard = TARGET_LOCK.write();
734
            unsafe { LLVMInitializeWebAssemblyTargetInfo() };
735
        }
736
737
        if config.asm_printer {
738
            let _guard = TARGET_LOCK.write();
739
            unsafe { LLVMInitializeWebAssemblyAsmPrinter() };
740
        }
741
742
        if config.asm_parser {
743
            let _guard = TARGET_LOCK.write();
744
            unsafe { LLVMInitializeWebAssemblyAsmParser() };
745
        }
746
747
        if config.disassembler {
748
            let _guard = TARGET_LOCK.write();
749
            unsafe { LLVMInitializeWebAssemblyDisassembler() };
750
        }
751
752
        if config.machine_code {
753
            let _guard = TARGET_LOCK.write();
754
            unsafe { LLVMInitializeWebAssemblyTargetMC() };
755
        }
756
    }
757
758
0
    pub fn initialize_native(config: &InitializationConfig) -> Result<(), String> {
759
0
        use llvm_sys::target::{
760
0
            LLVM_InitializeNativeAsmParser, LLVM_InitializeNativeAsmPrinter, LLVM_InitializeNativeDisassembler,
761
0
            LLVM_InitializeNativeTarget,
762
0
        };
763
0
764
0
        if config.base {
765
0
            let _guard = TARGET_LOCK.write();
766
0
            let code = unsafe { LLVM_InitializeNativeTarget() };
767
0
768
0
            if code == 1 {
769
0
                return Err("Unknown error in initializing native target".into());
770
0
            }
771
0
        }
772
773
0
        if config.asm_printer {
774
0
            let _guard = TARGET_LOCK.write();
775
0
            let code = unsafe { LLVM_InitializeNativeAsmPrinter() };
776
0
777
0
            if code == 1 {
778
0
                return Err("Unknown error in initializing native asm printer".into());
779
0
            }
780
0
        }
781
782
0
        if config.asm_parser {
783
0
            let _guard = TARGET_LOCK.write();
784
0
            let code = unsafe { LLVM_InitializeNativeAsmParser() };
785
0
786
0
            if code == 1 {
787
                // REVIEW: Does parser need to go before printer?
788
0
                return Err("Unknown error in initializing native asm parser".into());
789
0
            }
790
0
        }
791
792
0
        if config.disassembler {
793
0
            let _guard = TARGET_LOCK.write();
794
0
            let code = unsafe { LLVM_InitializeNativeDisassembler() };
795
0
796
0
            if code == 1 {
797
0
                return Err("Unknown error in initializing native disassembler".into());
798
0
            }
799
0
        }
800
801
0
        Ok(())
802
0
    }
803
804
0
    pub fn initialize_all(config: &InitializationConfig) {
805
0
        use llvm_sys::target::{
806
0
            LLVM_InitializeAllAsmParsers, LLVM_InitializeAllAsmPrinters, LLVM_InitializeAllDisassemblers,
807
0
            LLVM_InitializeAllTargetInfos, LLVM_InitializeAllTargetMCs, LLVM_InitializeAllTargets,
808
0
        };
809
0
810
0
        if config.base {
811
0
            let _guard = TARGET_LOCK.write();
812
0
            unsafe { LLVM_InitializeAllTargets() };
813
0
        }
814
815
0
        if config.info {
816
0
            let _guard = TARGET_LOCK.write();
817
0
            unsafe { LLVM_InitializeAllTargetInfos() };
818
0
        }
819
820
0
        if config.asm_parser {
821
0
            let _guard = TARGET_LOCK.write();
822
0
            unsafe { LLVM_InitializeAllAsmParsers() };
823
0
        }
824
825
0
        if config.asm_printer {
826
0
            let _guard = TARGET_LOCK.write();
827
0
            unsafe { LLVM_InitializeAllAsmPrinters() };
828
0
        }
829
830
0
        if config.disassembler {
831
0
            let _guard = TARGET_LOCK.write();
832
0
            unsafe { LLVM_InitializeAllDisassemblers() };
833
0
        }
834
835
0
        if config.machine_code {
836
0
            let _guard = TARGET_LOCK.write();
837
0
            unsafe { LLVM_InitializeAllTargetMCs() };
838
0
        }
839
0
    }
840
841
171k
    pub fn create_target_machine(
842
171k
        &self,
843
171k
        triple: &TargetTriple,
844
171k
        cpu: &str,
845
171k
        features: &str,
846
171k
        level: OptimizationLevel,
847
171k
        reloc_mode: RelocMode,
848
171k
        code_model: CodeModel,
849
171k
    ) -> Option<TargetMachine> {
850
171k
        let cpu = to_c_str(cpu);
851
171k
        let features = to_c_str(features);
852
171k
        let level = match level {
853
0
            OptimizationLevel::None => LLVMCodeGenOptLevel::LLVMCodeGenLevelNone,
854
0
            OptimizationLevel::Less => LLVMCodeGenOptLevel::LLVMCodeGenLevelLess,
855
0
            OptimizationLevel::Default => LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault,
856
171k
            OptimizationLevel::Aggressive => LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive,
857
        };
858
171k
        let code_model = match code_model {
859
0
            CodeModel::Default => LLVMCodeModel::LLVMCodeModelDefault,
860
0
            CodeModel::JITDefault => LLVMCodeModel::LLVMCodeModelJITDefault,
861
0
            CodeModel::Small => LLVMCodeModel::LLVMCodeModelSmall,
862
0
            CodeModel::Kernel => LLVMCodeModel::LLVMCodeModelKernel,
863
0
            CodeModel::Medium => LLVMCodeModel::LLVMCodeModelMedium,
864
171k
            CodeModel::Large => LLVMCodeModel::LLVMCodeModelLarge,
865
        };
866
171k
        let reloc_mode = match reloc_mode {
867
0
            RelocMode::Default => LLVMRelocMode::LLVMRelocDefault,
868
171k
            RelocMode::Static => LLVMRelocMode::LLVMRelocStatic,
869
0
            RelocMode::PIC => LLVMRelocMode::LLVMRelocPIC,
870
0
            RelocMode::DynamicNoPic => LLVMRelocMode::LLVMRelocDynamicNoPic,
871
        };
872
171k
        let target_machine = unsafe {
873
171k
            LLVMCreateTargetMachine(
874
171k
                self.target,
875
171k
                triple.as_ptr(),
876
171k
                cpu.as_ptr(),
877
171k
                features.as_ptr(),
878
171k
                level,
879
171k
                reloc_mode,
880
171k
                code_model,
881
171k
            )
882
171k
        };
883
171k
884
171k
        if target_machine.is_null() {
885
0
            return None;
886
171k
        }
887
171k
888
171k
        unsafe { Some(TargetMachine::new(target_machine)) }
889
171k
    }
890
891
0
    pub fn get_first() -> Option<Self> {
892
0
        let target = {
893
0
            let _guard = TARGET_LOCK.read();
894
0
            unsafe { LLVMGetFirstTarget() }
895
0
        };
896
0
897
0
        if target.is_null() {
898
0
            return None;
899
0
        }
900
0
901
0
        unsafe { Some(Target::new(target)) }
902
0
    }
903
904
0
    pub fn get_next(&self) -> Option<Self> {
905
0
        let target = unsafe { LLVMGetNextTarget(self.target) };
906
0
907
0
        if target.is_null() {
908
0
            return None;
909
0
        }
910
0
911
0
        unsafe { Some(Target::new(target)) }
912
0
    }
913
914
0
    pub fn get_name(&self) -> &CStr {
915
0
        unsafe { CStr::from_ptr(LLVMGetTargetName(self.target)) }
916
0
    }
917
918
0
    pub fn get_description(&self) -> &CStr {
919
0
        unsafe { CStr::from_ptr(LLVMGetTargetDescription(self.target)) }
920
0
    }
921
922
0
    pub fn from_name(name: &str) -> Option<Self> {
923
0
        let c_string = to_c_str(name);
924
0
925
0
        Self::from_name_raw(c_string.as_ptr())
926
0
    }
927
928
0
    pub(crate) fn from_name_raw(c_string: *const ::libc::c_char) -> Option<Self> {
929
0
        let target = {
930
0
            let _guard = TARGET_LOCK.read();
931
0
            unsafe { LLVMGetTargetFromName(c_string) }
932
0
        };
933
0
934
0
        if target.is_null() {
935
0
            return None;
936
0
        }
937
0
938
0
        unsafe { Some(Target::new(target)) }
939
0
    }
940
941
171k
    pub fn from_triple(triple: &TargetTriple) -> Result<Self, LLVMString> {
942
171k
        let mut target = ptr::null_mut();
943
171k
        let mut err_string = MaybeUninit::uninit();
944
171k
945
171k
        let code = {
946
171k
            let _guard = TARGET_LOCK.read();
947
171k
            unsafe { LLVMGetTargetFromTriple(triple.as_ptr(), &mut target, err_string.as_mut_ptr()) }
948
171k
        };
949
171k
950
171k
        if code == 1 {
951
            unsafe {
952
0
                return Err(LLVMString::new(err_string.assume_init()));
953
            }
954
171k
        }
955
171k
956
171k
        unsafe { Ok(Target::new(target)) }
957
171k
    }
958
959
0
    pub fn has_jit(&self) -> bool {
960
0
        unsafe { LLVMTargetHasJIT(self.target) == 1 }
961
0
    }
962
963
0
    pub fn has_target_machine(&self) -> bool {
964
0
        unsafe { LLVMTargetHasTargetMachine(self.target) == 1 }
965
0
    }
966
967
0
    pub fn has_asm_backend(&self) -> bool {
968
0
        unsafe { LLVMTargetHasAsmBackend(self.target) == 1 }
969
0
    }
970
}
971
972
#[derive(Debug)]
973
pub struct TargetMachine {
974
    pub(crate) target_machine: LLVMTargetMachineRef,
975
}
976
977
impl TargetMachine {
978
171k
    pub unsafe fn new(target_machine: LLVMTargetMachineRef) -> Self {
979
171k
        assert!(!target_machine.is_null());
980
981
171k
        TargetMachine { target_machine }
982
171k
    }
983
984
    /// Acquires the underlying raw pointer belonging to this `TargetMachine` type.
985
0
    pub fn as_mut_ptr(&self) -> LLVMTargetMachineRef {
986
0
        self.target_machine
987
0
    }
988
989
0
    pub fn get_target(&self) -> Target {
990
0
        unsafe { Target::new(LLVMGetTargetMachineTarget(self.target_machine)) }
991
0
    }
992
993
331k
    pub fn get_triple(&self) -> TargetTriple {
994
331k
        let str = unsafe { LLVMString::new(LLVMGetTargetMachineTriple(self.target_machine)) };
995
331k
996
331k
        unsafe { TargetTriple::new(str) }
997
331k
    }
998
999
    /// Gets the default triple for the current system.
1000
    ///
1001
    /// # Example
1002
    ///
1003
    /// ```no_run
1004
    /// use inkwell::targets::TargetMachine;
1005
    ///
1006
    /// let default_triple = TargetMachine::get_default_triple();
1007
    ///
1008
    /// assert_eq!(default_triple.as_str().to_str(), Ok("x86_64-pc-linux-gnu"));
1009
    /// ```
1010
0
    pub fn get_default_triple() -> TargetTriple {
1011
0
        let llvm_string = unsafe { LLVMString::new(LLVMGetDefaultTargetTriple()) };
1012
0
1013
0
        unsafe { TargetTriple::new(llvm_string) }
1014
0
    }
1015
1016
    #[llvm_versions(7.0..=latest)]
1017
0
    pub fn normalize_triple(triple: &TargetTriple) -> TargetTriple {
1018
0
        use llvm_sys::target_machine::LLVMNormalizeTargetTriple;
1019
0
1020
0
        let normalized = unsafe { LLVMString::new(LLVMNormalizeTargetTriple(triple.as_ptr())) };
1021
0
1022
0
        unsafe { TargetTriple::new(normalized) }
1023
0
    }
1024
1025
    /// Gets a string containing the host CPU's name (triple).
1026
    ///
1027
    /// # Example Output
1028
    ///
1029
    /// `x86_64-pc-linux-gnu`
1030
    #[llvm_versions(7.0..=latest)]
1031
0
    pub fn get_host_cpu_name() -> LLVMString {
1032
0
        use llvm_sys::target_machine::LLVMGetHostCPUName;
1033
0
1034
0
        unsafe { LLVMString::new(LLVMGetHostCPUName()) }
1035
0
    }
1036
1037
    /// Gets a comma separated list of supported features by the host CPU.
1038
    ///
1039
    /// # Example Output
1040
    ///
1041
    /// `+sse2,+cx16,+sahf,-tbm`
1042
    #[llvm_versions(7.0..=latest)]
1043
0
    pub fn get_host_cpu_features() -> LLVMString {
1044
0
        use llvm_sys::target_machine::LLVMGetHostCPUFeatures;
1045
0
1046
0
        unsafe { LLVMString::new(LLVMGetHostCPUFeatures()) }
1047
0
    }
1048
1049
0
    pub fn get_cpu(&self) -> LLVMString {
1050
0
        unsafe { LLVMString::new(LLVMGetTargetMachineCPU(self.target_machine)) }
1051
0
    }
1052
1053
0
    pub fn get_feature_string(&self) -> &CStr {
1054
0
        unsafe { CStr::from_ptr(LLVMGetTargetMachineFeatureString(self.target_machine)) }
1055
0
    }
1056
1057
    /// Create TargetData from this target machine
1058
    #[llvm_versions(4.0..=latest)]
1059
159k
    pub fn get_target_data(&self) -> TargetData {
1060
159k
        unsafe { TargetData::new(LLVMCreateTargetDataLayout(self.target_machine)) }
1061
159k
    }
1062
1063
0
    pub fn set_asm_verbosity(&self, verbosity: bool) {
1064
0
        unsafe { LLVMSetTargetMachineAsmVerbosity(self.target_machine, verbosity as i32) }
1065
0
    }
1066
1067
    // TODO: Move to PassManager?
1068
0
    pub fn add_analysis_passes<T>(&self, pass_manager: &PassManager<T>) {
1069
0
        unsafe { LLVMAddAnalysisPasses(self.target_machine, pass_manager.pass_manager) }
1070
0
    }
1071
1072
    /// Writes a `TargetMachine` to a `MemoryBuffer`.
1073
    ///
1074
    /// # Example
1075
    ///
1076
    /// ```no_run
1077
    /// use inkwell::OptimizationLevel;
1078
    /// use inkwell::context::Context;
1079
    /// use inkwell::targets::{CodeModel, RelocMode, FileType, Target, TargetMachine, TargetTriple, InitializationConfig};
1080
    ///
1081
    /// Target::initialize_x86(&InitializationConfig::default());
1082
    ///
1083
    /// let opt = OptimizationLevel::Default;
1084
    /// let reloc = RelocMode::Default;
1085
    /// let model = CodeModel::Default;
1086
    /// let target = Target::from_name("x86-64").unwrap();
1087
    /// let target_machine = target.create_target_machine(
1088
    ///     &TargetTriple::create("x86_64-pc-linux-gnu"),
1089
    ///     "x86-64",
1090
    ///     "+avx2",
1091
    ///     opt,
1092
    ///     reloc,
1093
    ///     model
1094
    /// )
1095
    /// .unwrap();
1096
    ///
1097
    /// let context = Context::create();
1098
    /// let module = context.create_module("my_module");
1099
    /// let void_type = context.void_type();
1100
    /// let fn_type = void_type.fn_type(&[], false);
1101
    ///
1102
    /// module.add_function("my_fn", fn_type, None);
1103
    ///
1104
    /// let buffer = target_machine.write_to_memory_buffer(&module, FileType::Assembly).unwrap();
1105
    /// ```
1106
159k
    pub fn write_to_memory_buffer(&self, module: &Module, file_type: FileType) -> Result<MemoryBuffer, LLVMString> {
1107
159k
        let mut memory_buffer = ptr::null_mut();
1108
159k
        let mut err_string = MaybeUninit::uninit();
1109
159k
        let return_code = unsafe {
1110
159k
            let module_ptr = module.module.get();
1111
159k
            let file_type_ptr = file_type.as_llvm_file_type();
1112
159k
1113
159k
            LLVMTargetMachineEmitToMemoryBuffer(
1114
159k
                self.target_machine,
1115
159k
                module_ptr,
1116
159k
                file_type_ptr,
1117
159k
                err_string.as_mut_ptr(),
1118
159k
                &mut memory_buffer,
1119
159k
            )
1120
159k
        };
1121
159k
1122
159k
        if return_code == 1 {
1123
            unsafe {
1124
0
                return Err(LLVMString::new(err_string.assume_init()));
1125
            }
1126
159k
        }
1127
159k
1128
159k
        unsafe { Ok(MemoryBuffer::new(memory_buffer)) }
1129
159k
    }
1130
1131
    /// Saves a `TargetMachine` to a file.
1132
    ///
1133
    /// # Example
1134
    ///
1135
    /// ```no_run
1136
    /// use inkwell::OptimizationLevel;
1137
    /// use inkwell::context::Context;
1138
    /// use inkwell::targets::{CodeModel, RelocMode, FileType, Target, TargetMachine, TargetTriple, InitializationConfig};
1139
    ///
1140
    /// use std::path::Path;
1141
    ///
1142
    /// Target::initialize_x86(&InitializationConfig::default());
1143
    ///
1144
    /// let opt = OptimizationLevel::Default;
1145
    /// let reloc = RelocMode::Default;
1146
    /// let model = CodeModel::Default;
1147
    /// let path = Path::new("/tmp/some/path/main.asm");
1148
    /// let target = Target::from_name("x86-64").unwrap();
1149
    /// let target_machine = target.create_target_machine(
1150
    ///     &TargetTriple::create("x86_64-pc-linux-gnu"),
1151
    ///     "x86-64",
1152
    ///     "+avx2",
1153
    ///     opt,
1154
    ///     reloc,
1155
    ///     model
1156
    /// )
1157
    /// .unwrap();
1158
    ///
1159
    /// let context = Context::create();
1160
    /// let module = context.create_module("my_module");
1161
    /// let void_type = context.void_type();
1162
    /// let fn_type = void_type.fn_type(&[], false);
1163
    ///
1164
    /// module.add_function("my_fn", fn_type, None);
1165
    ///
1166
    /// assert!(target_machine.write_to_file(&module, FileType::Object, &path).is_ok());
1167
    /// ```
1168
0
    pub fn write_to_file(&self, module: &Module, file_type: FileType, path: &Path) -> Result<(), LLVMString> {
1169
0
        let path = path.to_str().expect("Did not find a valid Unicode path string");
1170
0
        let path_c_string = to_c_str(path);
1171
0
        let mut err_string = MaybeUninit::uninit();
1172
0
        let return_code = unsafe {
1173
0
            // REVIEW: Why does LLVM need a mutable ptr to path...?
1174
0
            let module_ptr = module.module.get();
1175
0
            let path_ptr = path_c_string.as_ptr() as *mut _;
1176
0
            let file_type_ptr = file_type.as_llvm_file_type();
1177
0
1178
0
            LLVMTargetMachineEmitToFile(
1179
0
                self.target_machine,
1180
0
                module_ptr,
1181
0
                path_ptr,
1182
0
                file_type_ptr,
1183
0
                err_string.as_mut_ptr(),
1184
0
            )
1185
0
        };
1186
0
1187
0
        if return_code == 1 {
1188
            unsafe {
1189
0
                return Err(LLVMString::new(err_string.assume_init()));
1190
            }
1191
0
        }
1192
0
1193
0
        Ok(())
1194
0
    }
1195
}
1196
1197
impl Drop for TargetMachine {
1198
171k
    fn drop(&mut self) {
1199
171k
        unsafe { LLVMDisposeTargetMachine(self.target_machine) }
1200
171k
    }
1201
}
1202
1203
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
1204
pub enum ByteOrdering {
1205
    BigEndian,
1206
    LittleEndian,
1207
}
1208
1209
#[derive(PartialEq, Eq, Debug)]
1210
pub struct TargetData {
1211
    pub(crate) target_data: LLVMTargetDataRef,
1212
}
1213
1214
impl TargetData {
1215
159k
    pub unsafe fn new(target_data: LLVMTargetDataRef) -> TargetData {
1216
159k
        assert!(!target_data.is_null());
1217
1218
159k
        TargetData { target_data }
1219
159k
    }
1220
1221
    /// Acquires the underlying raw pointer belonging to this `TargetData` type.
1222
0
    pub fn as_mut_ptr(&self) -> LLVMTargetDataRef {
1223
0
        self.target_data
1224
0
    }
1225
1226
    /// Gets the `IntType` representing a bit width of a pointer. It will be assigned the referenced context.
1227
    ///
1228
    /// # Example
1229
    ///
1230
    /// ```no_run
1231
    /// use inkwell::OptimizationLevel;
1232
    /// use inkwell::context::Context;
1233
    /// use inkwell::targets::{InitializationConfig, Target};
1234
    ///
1235
    /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
1236
    ///
1237
    /// let context = Context::create();
1238
    /// let module = context.create_module("sum");
1239
    /// let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
1240
    /// let target_data = execution_engine.get_target_data();
1241
    /// let int_type = target_data.ptr_sized_int_type_in_context(&context, None);
1242
    /// ```
1243
    #[deprecated(note = "This method will be removed in the future. Please use Context::ptr_sized_int_type instead.")]
1244
0
    pub fn ptr_sized_int_type_in_context<'ctx>(
1245
0
        &self,
1246
0
        context: impl AsContextRef<'ctx>,
1247
0
        address_space: Option<AddressSpace>,
1248
0
    ) -> IntType<'ctx> {
1249
0
        let int_type_ptr = match address_space {
1250
0
            Some(address_space) => unsafe {
1251
0
                LLVMIntPtrTypeForASInContext(context.as_ctx_ref(), self.target_data, address_space.0)
1252
            },
1253
0
            None => unsafe { LLVMIntPtrTypeInContext(context.as_ctx_ref(), self.target_data) },
1254
        };
1255
1256
0
        unsafe { IntType::new(int_type_ptr) }
1257
0
    }
1258
1259
159k
    pub fn get_data_layout(&self) -> DataLayout {
1260
159k
        unsafe { DataLayout::new_owned(LLVMCopyStringRepOfTargetData(self.target_data)) }
1261
159k
    }
1262
1263
    // REVIEW: Does this only work if Sized?
1264
0
    pub fn get_bit_size(&self, type_: &dyn AnyType) -> u64 {
1265
0
        unsafe { LLVMSizeOfTypeInBits(self.target_data, type_.as_type_ref()) }
1266
0
    }
1267
1268
    // TODOC: This can fail on LLVM's side(exit?), but it doesn't seem like we have any way to check this in rust
1269
0
    pub fn create(str_repr: &str) -> TargetData {
1270
0
        let c_string = to_c_str(str_repr);
1271
0
1272
0
        unsafe { TargetData::new(LLVMCreateTargetData(c_string.as_ptr())) }
1273
0
    }
1274
1275
0
    pub fn get_byte_ordering(&self) -> ByteOrdering {
1276
0
        let byte_ordering = unsafe { LLVMByteOrder(self.target_data) };
1277
0
1278
0
        match byte_ordering {
1279
0
            LLVMByteOrdering::LLVMBigEndian => ByteOrdering::BigEndian,
1280
0
            LLVMByteOrdering::LLVMLittleEndian => ByteOrdering::LittleEndian,
1281
        }
1282
0
    }
1283
1284
0
    pub fn get_pointer_byte_size(&self, address_space: Option<AddressSpace>) -> u32 {
1285
0
        match address_space {
1286
0
            Some(address_space) => unsafe { LLVMPointerSizeForAS(self.target_data, address_space.0) },
1287
0
            None => unsafe { LLVMPointerSize(self.target_data) },
1288
        }
1289
0
    }
1290
1291
0
    pub fn get_store_size(&self, type_: &dyn AnyType) -> u64 {
1292
0
        unsafe { LLVMStoreSizeOfType(self.target_data, type_.as_type_ref()) }
1293
0
    }
1294
1295
0
    pub fn get_abi_size(&self, type_: &dyn AnyType) -> u64 {
1296
0
        unsafe { LLVMABISizeOfType(self.target_data, type_.as_type_ref()) }
1297
0
    }
1298
1299
0
    pub fn get_abi_alignment(&self, type_: &dyn AnyType) -> u32 {
1300
0
        unsafe { LLVMABIAlignmentOfType(self.target_data, type_.as_type_ref()) }
1301
0
    }
1302
1303
0
    pub fn get_call_frame_alignment(&self, type_: &dyn AnyType) -> u32 {
1304
0
        unsafe { LLVMCallFrameAlignmentOfType(self.target_data, type_.as_type_ref()) }
1305
0
    }
1306
1307
0
    pub fn get_preferred_alignment(&self, type_: &dyn AnyType) -> u32 {
1308
0
        unsafe { LLVMPreferredAlignmentOfType(self.target_data, type_.as_type_ref()) }
1309
0
    }
1310
1311
0
    pub fn get_preferred_alignment_of_global(&self, value: &GlobalValue) -> u32 {
1312
0
        unsafe { LLVMPreferredAlignmentOfGlobal(self.target_data, value.as_value_ref()) }
1313
0
    }
1314
1315
0
    pub fn element_at_offset(&self, struct_type: &StructType, offset: u64) -> u32 {
1316
0
        unsafe { LLVMElementAtOffset(self.target_data, struct_type.as_type_ref(), offset) }
1317
0
    }
1318
1319
0
    pub fn offset_of_element(&self, struct_type: &StructType, element: u32) -> Option<u64> {
1320
0
        if element > struct_type.count_fields() - 1 {
1321
0
            return None;
1322
0
        }
1323
0
1324
0
        unsafe {
1325
0
            Some(LLVMOffsetOfElement(
1326
0
                self.target_data,
1327
0
                struct_type.as_type_ref(),
1328
0
                element,
1329
0
            ))
1330
        }
1331
0
    }
1332
}
1333
1334
impl Drop for TargetData {
1335
159k
    fn drop(&mut self) {
1336
159k
        unsafe { LLVMDisposeTargetData(self.target_data) }
1337
159k
    }
1338
}