summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/hir-ty/src/layout/target.rs
blob: 37b831652f565a4a28a4989dc49a0c5307d245a0 (plain)
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
//! Target dependent parameters needed for layouts

use std::sync::Arc;

use base_db::CrateId;
use hir_def::layout::{Endian, Size, TargetDataLayout};

use crate::db::HirDatabase;

pub fn target_data_layout_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<TargetDataLayout> {
    let crate_graph = db.crate_graph();
    let target_layout = &crate_graph[krate].target_layout;
    let cfg_options = &crate_graph[krate].cfg_options;
    Arc::new(
        target_layout
            .as_ref()
            .and_then(|it| TargetDataLayout::parse_from_llvm_datalayout_string(it).ok())
            .unwrap_or_else(|| {
                let endian = match cfg_options.get_cfg_values("target_endian").next() {
                    Some(x) if x.as_str() == "big" => Endian::Big,
                    _ => Endian::Little,
                };
                let pointer_size = Size::from_bytes(
                    match cfg_options.get_cfg_values("target_pointer_width").next() {
                        Some(x) => match x.as_str() {
                            "16" => 2,
                            "32" => 4,
                            _ => 8,
                        },
                        _ => 8,
                    },
                );
                TargetDataLayout { endian, pointer_size, ..TargetDataLayout::default() }
            }),
    )
}