1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) The pliron contributors
//! Safe(r) wrappers around [llvm_sys].
//!
//! The wrappers provide (some) safety by asserting that the concrete C++
//! types of arguments match the expected C++ type. This minimizes
//! undefined behavior / invalid memory accesses. For example:
//! 1. `core::llvm_add_incoming(phi_node: LLVMValueRef, ...)`
//! checks that `phi_node` is indeed a C++ `PHINode`.
//! 2. `core::llvm_count_param_types(ty: LLVMTypeRef)`
//! checks that `ty` is a function type.
//!
//! We do not check for invalid IR that is caught by the verifier.
//! As a general guideline, ensure that the C-Types (which are C++ base classes)
//! match the C++ derived class expected by the callee, via assertions;
//! such as the PHINode: LLVMValueRef example above.
//! Type-checking the LLVM-IR itself is left to the verifier, with exceptions.
//! Exceptions include constraints on `LLVMTypeRef`, for example `ArrayType`'s
//! element must satisfy `llvm_is_valid_array_element_type`. This isn't verified
//! by the verifier.
//!
//! Note that these wrappers do not provide full memory safety.
//! Values returned by LLVM are not lifetime-managed / bound.
//! So you can easily create use-after-free scenarios by deleting / erasing
//! a value / basic-block etc and then using it later.
//!
//! This inherent "unsafety" exists in `inkwell` too, even though Inkwell binds
//! values returned by LLVM to a context, which isn't sufficient. For example,
//! use-after-free / undefined behavior:
//! ```unknown
//! let instruction = builder.build_int_add(...);
//! instruction.erase_from_basic_block();
//! instruction.get_opcode(); // use-after-free / undefined behavior!
//! ```
//! As another example, `BasicBlock::delete` is marked `unsafe`, but it isn't
//! the `delete` that is unsafe, but a subsequent use of the deleted block,
//! (which need not be marked `unsafe`) that is unsafe: an illusion of safety.
use LLVMBool;
use ;
/// Create an uninitialized vector with given length.
unsafe
/// Convert a null-terminated, possibly null, C string to [String].
/// Convert a non-null-terminated, possibly null C string to [String]
/// Convert a C array to a Rust vec.
/// Convert a value to `bool`
/// This function takes in a Rust string and either:
///
/// A) Finds a terminating null byte in the Rust string and can reference it directly like a C string.
///
/// B) Finds no null byte and allocates a new C string based on the input Rust string.
///
/// This function and its test are taken from the [inkwell](https://github.com/thedan64/inkwell/) project
pub