Skip to content

Commit eea6e84

Browse files
committed
parse_clang_def partial imp
1 parent c6c5b7b commit eea6e84

File tree

3 files changed

+155
-27
lines changed

3 files changed

+155
-27
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rust-project.json
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
use std::collections::HashMap;
2+
3+
/*
4+
struct SystemProperties {
5+
char_bit: u8,
6+
pointer_size: u32,
7+
pointer_width: u32,
8+
//add other system wide properties as needed
9+
}
10+
//
11+
12+
impl SystemProperties {
13+
//constructor for system properties
14+
fn from_defines(output: &str) -> Self {
15+
let char_bit = output
16+
.lines()
17+
.find(|line| line.contains("__CHAR_BIT__"))
18+
.and_then(|line| line.split_whitespace().nth(2))
19+
.and_then(|value| value.parse().ok())
20+
.unwrap_or(8); //assumption can be made c standards require 8 bit char
21+
22+
let pointer_size = output
23+
.lines()
24+
.find(|line| line.contains("__POINTER_SIZE__"))
25+
.and_then(|line| line.split_whitespace().nth(2))
26+
.and_then(|value| value.parse().ok());
27+
28+
let pointer_width = output
29+
.line()
30+
.find(|line| line.contains("__POINTER_WIDTH__"))
31+
.and_then(|line| line.split_whitespace().nth(2))
32+
.and_then(|value| value.parse().ok());
33+
34+
if pointer_width.is_none() { //FIXME: should be an assert I believe
35+
eprintln!("Warning: Could not determine pointer width from Clang output");
36+
}
37+
38+
if pointer_size.is_none() {
39+
eprintln!("Warning: Could not determine pointer size from Clang output");
40+
}
41+
42+
SystemProperties {
43+
char_bit, pointer_size, pointer_width,
44+
}
45+
}
46+
47+
fn is_valid(&self) -> bool {
48+
self.pointer_size.is_some() && self.pointer_width.is_some()
49+
}
50+
}
51+
*/
52+
53+
#[derive(Debug)]
54+
struct CTypeInfo {
55+
size_in_bytes: Option<u32>,
56+
width_in_bytes: Option<u32>,
57+
is_unsigned: Option<bool>,
58+
}
59+
60+
impl CTypeInfo {
61+
fn new() -> self {
62+
Self {
63+
size_in_bytes: None,
64+
width_in_bytes: None,
65+
is_unsigned: None,
66+
}
67+
}
68+
}
69+
70+
fn parse_defines(output: &str) -> (HashMap<String, CTypeInfo>) {
71+
let mut types = HashMap::new();
72+
73+
74+
//first pass
75+
for line in output.lines() {
76+
if !line.starts_with("#define ") {
77+
continue;
78+
}
79+
80+
let parts: Vec<&str> = line.split_whitespace().collect();
81+
if parts.len() < 3 {
82+
continue;
83+
}
84+
85+
let define_name = parts[1];
86+
let value = match parts[2].parse::<u32>() {
87+
Ok(v) => v,
88+
Err(_) => continue,
89+
};
90+
91+
match define_name {
92+
// Size information
93+
s if s.starts_with("__SIZEOF_") => {
94+
let type_name = s.trim_start_matches("__SIZEOF_")
95+
.trim_end_matches("__")
96+
.to_lowercase();
97+
let type_info = types.entry(type_name).or_insert_with(CTypeInfo::new);
98+
type_info.size_in_bytes = Some(value);
99+
},
100+
// Width information
101+
w if w.ends_with("_WIDTH__") => {
102+
let type_name = w.trim_end_matches("_WIDTH__")
103+
.trim_start_matches("__")
104+
.to_lowercase();
105+
let type_info = types.entry(type_name).or_insert_with(CTypeInfo::new);
106+
type_info.width_in_bits = Some(value);
107+
},
108+
// Special case for char signedness
109+
"__CHAR_UNSIGNED__" => {
110+
let type_info = types.entry("char".to_string()).or_insert_with(CTypeInfo::new);
111+
type_info.is_unsigned = Some(true);
112+
},
113+
_ => {} //other cases, maybe
114+
}
115+
//hash map is now populated.
116+
//now need to extract all the necessary stuff
117+
}
118+
119+
//second pass
120+
for line in output.lines() {
121+
if !line.starts_with("#define ") {
122+
continue;
123+
}
124+
125+
let parts: Vec<&str> = line.split_whitespace().collect();
126+
if parts.len() < 3 {
127+
continue;
128+
}
129+
130+
let define_name = parts[1];
131+
132+
133+
}
134+
}

tests/run-make/core-ffi-typecheck/rmake.rs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,44 +29,37 @@ fn get_llvm_target(rust_target: &str) -> String {
2929
"--print", "target-spec-json",
3030
"--target", rust_target
3131
])
32-
.output()?;
33-
34-
if !output.status.success() {
35-
return Err("rustc command failed".into());
36-
}
37-
38-
let json_str = String::from_utf8(output.stdout)?;
32+
.output()
33+
.expect("Failed to get target spec");
3934

40-
for line in json_str.lines() {
41-
if line.contains("\"llvm-target\":") {
42-
if let Some(target) = line.split(':')
43-
.nth(1)
44-
.and_then(|s| s.trim().strip_prefix('"'))
45-
.and_then(|s| s.strip_suffix("\",")) {
46-
return Ok(target.to_string());
47-
}
48-
}
49-
}
35+
let json: serde_json::Value = serde_json::from_slice(&output.stdout)
36+
.expect("Failed to parse json target");
5037

51-
Err("could not find llvm-target in JSON output".into());
38+
json["llvm-target"].as_str()
39+
.expect("No llvm-target in spec")
40+
.to_string()
5241

5342
}
5443

55-
fn get_clang_definitions(target: &str) -> HashMap<String, String> {
44+
fn get_clang_definitions(llvm_target: &str) -> HashMap<String, String> {
5645

57-
}
46+
let output = Command::new("clang")
47+
.args([
48+
"-E",
49+
"-dM",
50+
"-x", "c",
51+
"/dev/null",
52+
"-target", llvm_target
53+
])
54+
.output()
55+
.expect("failed to run clang");
5856

59-
fn generate_compatibility_test(target: &str, definitions: &HashMap<String, String>) -> String {
57+
let defines = str::from_utf8(&output.stdout)
58+
.expect("Invalid clang output");
6059

6160
}
6261

6362
fn main() {
6463
//Get list of all targets
65-
let targets = get_target_list();
66-
67-
for target in targets {
68-
69-
}
70-
7164
println!("All C interop type compatibility checks passed");
7265
}

0 commit comments

Comments
 (0)