Skip to content

Commit 96bba97

Browse files
committed
ir: Grab target information from clang.
1 parent 5b8572f commit 96bba97

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ cexpr = "0.2"
4747
cfg-if = "0.1.0"
4848
# This kinda sucks: https://github.com/rust-lang/cargo/issues/1982
4949
clap = "2"
50-
clang-sys = { version = "0.22.0", features = ["runtime", "clang_3_9"] }
50+
clang-sys = { version = "0.22.0", features = ["runtime", "clang_6_0"] }
5151
lazy_static = "1"
5252
peeking_take_while = "0.1.2"
5353
quote = "0.3.15"

src/clang.rs

+32
Original file line numberDiff line numberDiff line change
@@ -1812,3 +1812,35 @@ impl Drop for EvalResult {
18121812
unsafe { clang_EvalResult_dispose(self.x) };
18131813
}
18141814
}
1815+
1816+
/// Target information obtained from libclang.
1817+
#[derive(Debug)]
1818+
pub struct TargetInfo {
1819+
/// The target triple.
1820+
pub triple: String,
1821+
/// The width of the pointer _in bits_.
1822+
pub pointer_width: usize,
1823+
}
1824+
1825+
impl TargetInfo {
1826+
/// Tries to obtain target information from libclang.
1827+
pub fn new(tu: &TranslationUnit) -> Option<Self> {
1828+
if !clang_getTranslationUnitTargetInfo::is_loaded() {
1829+
return None;
1830+
}
1831+
let triple;
1832+
let pointer_width;
1833+
unsafe {
1834+
let ti = clang_getTranslationUnitTargetInfo(tu.x);
1835+
triple = cxstring_into_string(clang_TargetInfo_getTriple(ti));
1836+
pointer_width = clang_TargetInfo_getPointerWidth(ti);
1837+
clang_TargetInfo_dispose(ti);
1838+
}
1839+
assert!(pointer_width > 0);
1840+
assert_eq!(pointer_width % 8, 0);
1841+
Some(TargetInfo {
1842+
triple,
1843+
pointer_width: pointer_width as usize,
1844+
})
1845+
}
1846+
}

src/ir/context.rs

+30-5
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,9 @@ pub struct BindgenContext {
366366
/// The translation unit for parsing.
367367
translation_unit: clang::TranslationUnit,
368368

369+
/// Target information that can be useful for some stuff.
370+
target_info: Option<clang::TargetInfo>,
371+
369372
/// The options given by the user via cli or other medium.
370373
options: BindgenOptions,
371374

@@ -503,6 +506,9 @@ impl<'ctx> WhitelistedItemsTraversal<'ctx> {
503506
}
504507
}
505508

509+
const HOST_TARGET: &'static str =
510+
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
511+
506512
/// Returns the effective target, and whether it was explicitly specified on the
507513
/// clang flags.
508514
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
@@ -521,8 +527,6 @@ fn find_effective_target(clang_args: &[String]) -> (String, bool) {
521527
return (t, false)
522528
}
523529

524-
const HOST_TARGET: &'static str =
525-
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
526530
(HOST_TARGET.to_owned(), false)
527531
}
528532

@@ -561,6 +565,17 @@ impl BindgenContext {
561565
).expect("TranslationUnit::parse failed")
562566
};
563567

568+
let target_info = clang::TargetInfo::new(&translation_unit);
569+
570+
#[cfg(debug_assertions)]
571+
{
572+
if let Some(ref ti) = target_info {
573+
if effective_target == HOST_TARGET {
574+
assert_eq!(ti.pointer_width / 8, mem::size_of::<*mut ()>());
575+
}
576+
}
577+
}
578+
564579
let root_module = Self::build_root_module(ItemId(0));
565580
let root_module_id = root_module.id().as_module_id_unchecked();
566581

@@ -578,9 +593,10 @@ impl BindgenContext {
578593
replacements: Default::default(),
579594
collected_typerefs: false,
580595
in_codegen: false,
581-
index: index,
582-
translation_unit: translation_unit,
583-
options: options,
596+
index,
597+
translation_unit,
598+
target_info,
599+
options,
584600
generated_bindegen_complex: Cell::new(false),
585601
whitelisted: None,
586602
codegen_items: None,
@@ -611,6 +627,15 @@ impl BindgenContext {
611627
Timer::new(name).with_output(self.options.time_phases)
612628
}
613629

630+
/// Returns the pointer width to use for the target for the current
631+
/// translation.
632+
pub fn target_pointer_size(&self) -> usize {
633+
if let Some(ref ti) = self.target_info {
634+
return ti.pointer_width / 8;
635+
}
636+
mem::size_of::<*mut ()>()
637+
}
638+
614639
/// Get the stack of partially parsed types that we are in the middle of
615640
/// parsing.
616641
pub fn currently_parsed_types(&self) -> &[PartialType] {

0 commit comments

Comments
 (0)