Skip to content

Commit 7f188eb

Browse files
committed
Add support for platform specific rules
1 parent 3b456f1 commit 7f188eb

8 files changed

Lines changed: 51 additions & 1 deletion

File tree

cpp2rust/converter/translation_rule.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ TypeRule ParseTypeRuleJSON(const llvm::json::Object &obj) {
130130
return rule;
131131
}
132132

133+
bool CfgMatchesHost(llvm::StringRef cfg) {
134+
#if defined(__linux__)
135+
return cfg == "linux";
136+
#elif defined(__APPLE__)
137+
return cfg == "macos";
138+
#else
139+
return false;
140+
#endif
141+
}
142+
133143
void LoadTgtFromIR(ExprRules &exprs, TypeRules &types,
134144
const std::filesystem::path &json_path) {
135145
auto buf = llvm::MemoryBuffer::getFile(json_path.string());
@@ -153,6 +163,10 @@ void LoadTgtFromIR(ExprRules &exprs, TypeRules &types,
153163
if (!obj)
154164
continue;
155165

166+
if (auto cfg = obj->getString("cfg"); cfg && !CfgMatchesHost(*cfg)) {
167+
continue;
168+
}
169+
156170
auto name = entry_name.str();
157171
if (name[0] == 'f') {
158172
exprs[std::move(name)] = ParseExprRuleJSON(*obj);

rule-preprocessor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ rules = { path = "../rules" }
99
ra_ap_syntax = "0.0.266"
1010
serde = { version = "1", features = ["derive"] }
1111
serde_json = "1"
12+
syn = "2"

rule-preprocessor/src/ir.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ pub struct TypeInfo {
4848

4949
#[derive(Debug, Clone, Serialize, Deserialize)]
5050
pub struct FnIr {
51-
// Fields ordered alphabetically to match the old serde_json::Map output
5251
pub body: Vec<BodyFragment>,
5352
#[serde(skip_serializing_if = "Option::is_none")]
53+
pub cfg: Option<String>,
54+
#[serde(skip_serializing_if = "Option::is_none")]
5455
pub generics: Option<BTreeMap<String, Vec<String>>>,
5556
#[serde(skip_serializing_if = "Option::is_none")]
5657
pub multi_statement: Option<bool>,

rule-preprocessor/src/syntactic.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,31 @@ impl<'a> FnIrBuilder<'a> {
258258
Self { fn_item }
259259
}
260260

261+
fn cfg_target_os(&self) -> Option<String> {
262+
use ast::HasAttrs;
263+
for attr in self.fn_item.attrs() {
264+
let meta_text = attr.meta()?.syntax().text().to_string();
265+
let syn::Meta::List(list) = syn::parse_str(&meta_text).ok()? else {
266+
continue;
267+
};
268+
if !list.path.is_ident("cfg") {
269+
continue;
270+
}
271+
let mut found = None;
272+
let _ = list.parse_nested_meta(|nested| {
273+
if nested.path.is_ident("target_os") {
274+
let lit: syn::LitStr = nested.value()?.parse()?;
275+
found = Some(lit.value());
276+
}
277+
Ok(())
278+
});
279+
if found.is_some() {
280+
return found;
281+
}
282+
}
283+
None
284+
}
285+
261286
fn params(&self) -> Vec<ParamInfo> {
262287
let mut params = Vec::new();
263288
let Some(param_list) = self.fn_item.param_list() else {
@@ -499,6 +524,7 @@ impl<'a> FnIrBuilder<'a> {
499524
},
500525
multi_statement,
501526
body,
527+
cfg: self.cfg_target_os(),
502528
};
503529
ir.validate(&format!("{}:{}", path.display(), fn_name));
504530
ir

rules/socket/ir_unsafe.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"text": "libc::SOCK_CLOEXEC"
3636
}
3737
],
38+
"cfg": "linux",
3839
"return_type": {
3940
"type": "i32"
4041
}
@@ -45,6 +46,7 @@
4546
"text": "libc::SOCK_NONBLOCK"
4647
}
4748
],
49+
"cfg": "linux",
4850
"return_type": {
4951
"type": "i32"
5052
}

rules/socket/src.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ int f3() {
1313
return SOCK_DGRAM;
1414
}
1515

16+
#ifdef __linux__
1617
int f4() {
1718
return SOCK_CLOEXEC;
1819
}
1920

2021
int f5() {
2122
return SOCK_NONBLOCK;
2223
}
24+
#endif

rules/socket/tgt_unsafe.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ unsafe fn f3() -> i32 {
1010
libc::SOCK_DGRAM
1111
}
1212

13+
#[cfg(target_os = "linux")]
1314
unsafe fn f4() -> i32 {
1415
libc::SOCK_CLOEXEC
1516
}
1617

18+
#[cfg(target_os = "linux")]
1719
unsafe fn f5() -> i32 {
1820
libc::SOCK_NONBLOCK
1921
}

tests/unit/socket_type_constants.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ int main() {
66
assert(SOCK_STREAM == 1);
77
assert(SOCK_DGRAM == 2);
88

9+
#ifdef __linux__
910
int x = SOCK_STREAM | SOCK_CLOEXEC;
1011
assert((x & SOCK_STREAM) == SOCK_STREAM);
1112
assert((x & SOCK_CLOEXEC) == SOCK_CLOEXEC);
1213

1314
int y = SOCK_DGRAM | SOCK_NONBLOCK;
1415
assert((y & SOCK_DGRAM) == SOCK_DGRAM);
1516
assert((y & SOCK_NONBLOCK) == SOCK_NONBLOCK);
17+
#endif
1618

1719
return 0;
1820
}

0 commit comments

Comments
 (0)