summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--src/clang.rs32
-rw-r--r--src/ir/context.rs35
3 files changed, 63 insertions, 6 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 851404dc..4c799576 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,7 +47,7 @@ cexpr = "0.2"
cfg-if = "0.1.0"
# This kinda sucks: https://github.com/rust-lang/cargo/issues/1982
clap = "2"
-clang-sys = { version = "0.22.0", features = ["runtime", "clang_3_9"] }
+clang-sys = { version = "0.22.0", features = ["runtime", "clang_6_0"] }
lazy_static = "1"
peeking_take_while = "0.1.2"
quote = "0.3.15"
diff --git a/src/clang.rs b/src/clang.rs
index cb873994..04d5c9d3 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -1812,3 +1812,35 @@ impl Drop for EvalResult {
unsafe { clang_EvalResult_dispose(self.x) };
}
}
+
+/// Target information obtained from libclang.
+#[derive(Debug)]
+pub struct TargetInfo {
+ /// The target triple.
+ pub triple: String,
+ /// The width of the pointer _in bits_.
+ pub pointer_width: usize,
+}
+
+impl TargetInfo {
+ /// Tries to obtain target information from libclang.
+ pub fn new(tu: &TranslationUnit) -> Option<Self> {
+ if !clang_getTranslationUnitTargetInfo::is_loaded() {
+ return None;
+ }
+ let triple;
+ let pointer_width;
+ unsafe {
+ let ti = clang_getTranslationUnitTargetInfo(tu.x);
+ triple = cxstring_into_string(clang_TargetInfo_getTriple(ti));
+ pointer_width = clang_TargetInfo_getPointerWidth(ti);
+ clang_TargetInfo_dispose(ti);
+ }
+ assert!(pointer_width > 0);
+ assert_eq!(pointer_width % 8, 0);
+ Some(TargetInfo {
+ triple,
+ pointer_width: pointer_width as usize,
+ })
+ }
+}
diff --git a/src/ir/context.rs b/src/ir/context.rs
index b453378d..07863809 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -366,6 +366,9 @@ pub struct BindgenContext {
/// The translation unit for parsing.
translation_unit: clang::TranslationUnit,
+ /// Target information that can be useful for some stuff.
+ target_info: Option<clang::TargetInfo>,
+
/// The options given by the user via cli or other medium.
options: BindgenOptions,
@@ -503,6 +506,9 @@ impl<'ctx> WhitelistedItemsTraversal<'ctx> {
}
}
+const HOST_TARGET: &'static str =
+ include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
+
/// Returns the effective target, and whether it was explicitly specified on the
/// clang flags.
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
@@ -521,8 +527,6 @@ fn find_effective_target(clang_args: &[String]) -> (String, bool) {
return (t, false)
}
- const HOST_TARGET: &'static str =
- include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
(HOST_TARGET.to_owned(), false)
}
@@ -561,6 +565,17 @@ impl BindgenContext {
).expect("TranslationUnit::parse failed")
};
+ let target_info = clang::TargetInfo::new(&translation_unit);
+
+ #[cfg(debug_assertions)]
+ {
+ if let Some(ref ti) = target_info {
+ if effective_target == HOST_TARGET {
+ assert_eq!(ti.pointer_width / 8, mem::size_of::<*mut ()>());
+ }
+ }
+ }
+
let root_module = Self::build_root_module(ItemId(0));
let root_module_id = root_module.id().as_module_id_unchecked();
@@ -578,9 +593,10 @@ impl BindgenContext {
replacements: Default::default(),
collected_typerefs: false,
in_codegen: false,
- index: index,
- translation_unit: translation_unit,
- options: options,
+ index,
+ translation_unit,
+ target_info,
+ options,
generated_bindegen_complex: Cell::new(false),
whitelisted: None,
codegen_items: None,
@@ -611,6 +627,15 @@ impl BindgenContext {
Timer::new(name).with_output(self.options.time_phases)
}
+ /// Returns the pointer width to use for the target for the current
+ /// translation.
+ pub fn target_pointer_size(&self) -> usize {
+ if let Some(ref ti) = self.target_info {
+ return ti.pointer_width / 8;
+ }
+ mem::size_of::<*mut ()>()
+ }
+
/// Get the stack of partially parsed types that we are in the middle of
/// parsing.
pub fn currently_parsed_types(&self) -> &[PartialType] {