33use std:: sync:: Arc ;
44
55use base_db:: CrateId ;
6- use hir_def:: layout:: { TargetDataLayout , TargetDataLayoutErrors } ;
6+ use hir_def:: layout:: { Endian , Size , TargetDataLayout } ;
77
88use crate :: db:: HirDatabase ;
99
10- use hir_def:: layout:: { AbiAndPrefAlign , AddressSpace , Align , Endian , Size } ;
11-
1210pub fn target_data_layout_query ( db : & dyn HirDatabase , krate : CrateId ) -> Arc < TargetDataLayout > {
1311 let crate_graph = db. crate_graph ( ) ;
1412 let target_layout = & crate_graph[ krate] . target_layout ;
1513 let cfg_options = & crate_graph[ krate] . cfg_options ;
1614 Arc :: new (
1715 target_layout
1816 . as_ref ( )
19- . and_then ( |it| parse_from_llvm_datalayout_string ( it) . ok ( ) )
17+ . and_then ( |it| TargetDataLayout :: parse_from_llvm_datalayout_string ( it) . ok ( ) )
2018 . unwrap_or_else ( || {
2119 let endian = match cfg_options. get_cfg_values ( "target_endian" ) . next ( ) {
2220 Some ( x) if x. as_str ( ) == "big" => Endian :: Big ,
@@ -36,96 +34,3 @@ pub fn target_data_layout_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Tar
3634 } ) ,
3735 )
3836}
39-
40- /// copied from rustc as it is not exposed yet
41- fn parse_from_llvm_datalayout_string < ' a > (
42- input : & ' a str ,
43- ) -> Result < TargetDataLayout , TargetDataLayoutErrors < ' a > > {
44- // Parse an address space index from a string.
45- let parse_address_space = |s : & ' a str , cause : & ' a str | {
46- s. parse :: < u32 > ( ) . map ( AddressSpace ) . map_err ( |err| {
47- TargetDataLayoutErrors :: InvalidAddressSpace { addr_space : s, cause, err }
48- } )
49- } ;
50-
51- // Parse a bit count from a string.
52- let parse_bits = |s : & ' a str , kind : & ' a str , cause : & ' a str | {
53- s. parse :: < u64 > ( ) . map_err ( |err| TargetDataLayoutErrors :: InvalidBits {
54- kind,
55- bit : s,
56- cause,
57- err,
58- } )
59- } ;
60-
61- // Parse a size string.
62- let size = |s : & ' a str , cause : & ' a str | parse_bits ( s, "size" , cause) . map ( Size :: from_bits) ;
63-
64- // Parse an alignment string.
65- let align = |s : & [ & ' a str ] , cause : & ' a str | {
66- if s. is_empty ( ) {
67- return Err ( TargetDataLayoutErrors :: MissingAlignment { cause } ) ;
68- }
69- let align_from_bits = |bits| {
70- Align :: from_bits ( bits)
71- . map_err ( |err| TargetDataLayoutErrors :: InvalidAlignment { cause, err } )
72- } ;
73- let abi = parse_bits ( s[ 0 ] , "alignment" , cause) ?;
74- let pref = s. get ( 1 ) . map_or ( Ok ( abi) , |pref| parse_bits ( pref, "alignment" , cause) ) ?;
75- Ok ( AbiAndPrefAlign { abi : align_from_bits ( abi) ?, pref : align_from_bits ( pref) ? } )
76- } ;
77-
78- let mut dl = TargetDataLayout :: default ( ) ;
79- let mut i128_align_src = 64 ;
80- for spec in input. split ( '-' ) {
81- let spec_parts = spec. split ( ':' ) . collect :: < Vec < _ > > ( ) ;
82-
83- match & * spec_parts {
84- [ "e" ] => dl. endian = Endian :: Little ,
85- [ "E" ] => dl. endian = Endian :: Big ,
86- [ p] if p. starts_with ( 'P' ) => {
87- dl. instruction_address_space = parse_address_space ( & p[ 1 ..] , "P" ) ?
88- }
89- [ "a" , ref a @ ..] => dl. aggregate_align = align ( a, "a" ) ?,
90- [ "f32" , ref a @ ..] => dl. f32_align = align ( a, "f32" ) ?,
91- [ "f64" , ref a @ ..] => dl. f64_align = align ( a, "f64" ) ?,
92- [ p @ "p" , s, ref a @ ..] | [ p @ "p0" , s, ref a @ ..] => {
93- dl. pointer_size = size ( s, p) ?;
94- dl. pointer_align = align ( a, p) ?;
95- }
96- [ s, ref a @ ..] if s. starts_with ( 'i' ) => {
97- let Ok ( bits) = s[ 1 ..] . parse :: < u64 > ( ) else {
98- size ( & s[ 1 ..] , "i" ) ?; // For the user error.
99- continue ;
100- } ;
101- let a = align ( a, s) ?;
102- match bits {
103- 1 => dl. i1_align = a,
104- 8 => dl. i8_align = a,
105- 16 => dl. i16_align = a,
106- 32 => dl. i32_align = a,
107- 64 => dl. i64_align = a,
108- _ => { }
109- }
110- if bits >= i128_align_src && bits <= 128 {
111- // Default alignment for i128 is decided by taking the alignment of
112- // largest-sized i{64..=128}.
113- i128_align_src = bits;
114- dl. i128_align = a;
115- }
116- }
117- [ s, ref a @ ..] if s. starts_with ( 'v' ) => {
118- let v_size = size ( & s[ 1 ..] , "v" ) ?;
119- let a = align ( a, s) ?;
120- if let Some ( v) = dl. vector_align . iter_mut ( ) . find ( |v| v. 0 == v_size) {
121- v. 1 = a;
122- continue ;
123- }
124- // No existing entry, add a new one.
125- dl. vector_align . push ( ( v_size, a) ) ;
126- }
127- _ => { } // Ignore everything else.
128- }
129- }
130- Ok ( dl)
131- }
0 commit comments