1#![allow(clippy::needless_lifetimes)]
18
19extern crate gccjit_sys;
20
21mod asm;
22mod types;
23mod context;
24mod object;
25mod location;
26mod field;
27mod structs;
28mod lvalue;
29mod rvalue;
30mod parameter;
31mod function;
32mod block;
33#[cfg(feature="master")]
34mod target_info;
35
36#[cfg(any(feature="dlopen", feature="master"))]
37use std::ffi::CStr;
38#[cfg(feature="dlopen")]
39use std::sync::OnceLock;
40
41pub use context::Context;
42pub use context::CType;
43pub use context::GlobalKind;
44pub use context::OptimizationLevel;
45pub use context::CompileResult;
46pub use context::OutputKind;
47pub use location::Location;
48pub use object::Object;
49pub use object::ToObject;
50pub use types::FunctionPtrType;
51pub use types::Type;
52pub use types::Typeable;
53#[cfg(feature="master")]
54pub use types::TypeAttribute;
55pub use field::Field;
56pub use structs::Struct;
57#[cfg(feature="master")]
58pub use lvalue::{VarAttribute, Visibility};
59pub use lvalue::{LValue, TlsModel, ToLValue};
60pub use rvalue::{RValue, ToRValue};
61pub use parameter::Parameter;
62#[cfg(feature="master")]
63pub use function::FnAttribute;
64pub use function::{Function, FunctionType};
65pub use block::{Block, BinaryOp, UnaryOp, ComparisonOp};
66#[cfg(feature="master")]
67pub use target_info::TargetInfo;
68
69use gccjit_sys::Libgccjit;
70
71#[cfg(feature="master")]
72pub fn set_global_personality_function_name(name: &'static [u8]) {
73 debug_assert!(name.ends_with(b"\0"), "Expecting a NUL-terminated C string");
74 with_lib(|lib| {
75 unsafe {
76 lib.gcc_jit_set_global_personality_function_name(name.as_ptr() as *const _);
77 }
78 })
79}
80
81#[derive(Debug)]
82pub struct Version {
83 pub major: i32,
84 pub minor: i32,
85 pub patch: i32,
86}
87
88impl Version {
89 pub fn get() -> Self {
90 with_lib(|lib| {
91 unsafe {
92 Self {
93 major: lib.gcc_jit_version_major(),
94 minor: lib.gcc_jit_version_minor(),
95 patch: lib.gcc_jit_version_patchlevel(),
96 }
97 }
98 })
99 }
100}
101
102#[cfg(feature="master")]
103pub fn is_lto_supported() -> bool {
104 with_lib(|lib| {
105 unsafe {
106 lib.gcc_jit_is_lto_supported()
107 }
108 })
109}
110
111#[cfg(not(feature="dlopen"))]
112fn with_lib<T, F: Fn(&Libgccjit) -> T>(callback: F) -> T {
113 callback(&LIB)
114}
115
116#[cfg(feature="dlopen")]
117fn with_lib<T, F: Fn(&Libgccjit) -> T>(callback: F) -> T {
118 let lib = LIB.get().and_then(|lib| lib.as_ref());
119 match lib {
120 Some(lib) => callback(lib),
121 None => panic!("libgccjit needs to be loaded by calling load() before attempting to do any operation"),
122 }
123}
124
125#[cfg(feature="dlopen")]
127pub fn load(path: &CStr) -> Result<(), String> {
128 let mut result = Ok(());
129 LIB.get_or_init(|| {
130 let lib = unsafe { Libgccjit::open(path) };
131 match lib {
132 Ok(lib) => Some(lib),
133 Err(error) => {
134 result = Err(error);
135 None
136 },
137 }
138 });
139 result
140}
141
142#[cfg(feature="dlopen")]
143pub fn is_loaded() -> bool {
144 LIB.get().is_some()
145}
146
147#[cfg(feature="dlopen")]
148pub static LIB: OnceLock<Option<Libgccjit>> = OnceLock::new();
149
150#[cfg(not(feature="dlopen"))]
152static LIB: Libgccjit = Libgccjit::new();
153
154#[cfg(feature="master")]
155pub fn set_lang_name(lang_name: &'static CStr) {
156 unsafe {
157 with_lib(|lib| {
158 lib.gcc_jit_set_lang_name(lang_name.as_ptr());
159 });
160 }
161}