Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cpp2rust/converter/translation_rule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ TypeRule ParseTypeRuleJSON(const llvm::json::Object &obj) {
return rule;
}

bool TargetOSMatchesHost(llvm::StringRef target_os) {
#if defined(__linux__)
return target_os == "linux";
#elif defined(__APPLE__)
return target_os == "macos";
#else
return false;
#endif
}

void LoadTgtFromIR(ExprRules &exprs, TypeRules &types,
const std::filesystem::path &json_path) {
auto buf = llvm::MemoryBuffer::getFile(json_path.string());
Expand All @@ -153,6 +163,11 @@ void LoadTgtFromIR(ExprRules &exprs, TypeRules &types,
if (!obj)
continue;

if (auto target_os = obj->getString("target_os");
target_os && !TargetOSMatchesHost(*target_os)) {
continue;
}

auto name = entry_name.str();
if (name[0] == 'f') {
exprs[std::move(name)] = ParseExprRuleJSON(*obj);
Expand Down
1 change: 1 addition & 0 deletions rule-preprocessor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ rules = { path = "../rules" }
ra_ap_syntax = "0.0.266"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
syn = "2"
3 changes: 2 additions & 1 deletion rule-preprocessor/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ pub struct TypeInfo {

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FnIr {
// Fields ordered alphabetically to match the old serde_json::Map output
pub body: Vec<BodyFragment>,
#[serde(skip_serializing_if = "Option::is_none")]
pub generics: Option<BTreeMap<String, Vec<String>>>,
Expand All @@ -58,6 +57,8 @@ pub struct FnIr {
pub params: Option<BTreeMap<String, TypeInfo>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub return_type: Option<TypeInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_os: Option<String>,
}

impl FnIr {
Expand Down
26 changes: 26 additions & 0 deletions rule-preprocessor/src/syntactic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,31 @@ impl<'a> FnIrBuilder<'a> {
Self { fn_item }
}

fn get_target_os(&self) -> Option<String> {
use ast::HasAttrs;
for attr in self.fn_item.attrs() {
let meta_text = attr.meta()?.syntax().text().to_string();
let syn::Meta::List(list) = syn::parse_str(&meta_text).ok()? else {
continue;
};
if !list.path.is_ident("cfg") {
continue;
}
let mut found = None;
let _ = list.parse_nested_meta(|nested| {
if nested.path.is_ident("target_os") {
let lit: syn::LitStr = nested.value()?.parse()?;
found = Some(lit.value());
}
Ok(())
});
if found.is_some() {
return found;
}
}
None
}

fn params(&self) -> Vec<ParamInfo> {
let mut params = Vec::new();
let Some(param_list) = self.fn_item.param_list() else {
Expand Down Expand Up @@ -499,6 +524,7 @@ impl<'a> FnIrBuilder<'a> {
},
multi_statement,
body,
target_os: self.get_target_os(),
};
ir.validate(&format!("{}:{}", path.display(), fn_name));
ir
Expand Down
42 changes: 42 additions & 0 deletions rules/socket/ir_unsafe.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,47 @@
"return_type": {
"type": "i32"
}
},
"f2": {
"body": [
{
"text": "libc::SOCK_STREAM"
}
],
"return_type": {
"type": "i32"
}
},
"f3": {
"body": [
{
"text": "libc::SOCK_DGRAM"
}
],
"return_type": {
"type": "i32"
}
},
"f4": {
"body": [
{
"text": "libc::SOCK_CLOEXEC"
}
],
"return_type": {
"type": "i32"
},
"target_os": "linux"
},
"f5": {
"body": [
{
"text": "libc::SOCK_NONBLOCK"
}
],
"return_type": {
"type": "i32"
},
"target_os": "linux"
}
}
18 changes: 18 additions & 0 deletions rules/socket/src.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,21 @@
int f1() {
return MSG_NOSIGNAL;
}

int f2() {
return SOCK_STREAM;
}

int f3() {
return SOCK_DGRAM;
}

#ifdef __linux__
int f4() {
return SOCK_CLOEXEC;
}

int f5() {
return SOCK_NONBLOCK;
}
#endif
18 changes: 18 additions & 0 deletions rules/socket/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
unsafe fn f1() -> i32 {
libc::MSG_NOSIGNAL
}

unsafe fn f2() -> i32 {
libc::SOCK_STREAM
}

unsafe fn f3() -> i32 {
libc::SOCK_DGRAM
}

#[cfg(target_os = "linux")]
unsafe fn f4() -> i32 {
libc::SOCK_CLOEXEC
}

#[cfg(target_os = "linux")]
unsafe fn f5() -> i32 {
libc::SOCK_NONBLOCK
}
16 changes: 16 additions & 0 deletions tests/unit/out/refcount/socket_type_constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
extern crate libcc2rs;
use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
assert!((((libc::SOCK_STREAM == 1) as i32) != 0));
assert!((((libc::SOCK_DGRAM == 2) as i32) != 0));
return 0;
}
18 changes: 18 additions & 0 deletions tests/unit/out/unsafe/socket_type_constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
extern crate libc;
use libc::*;
extern crate libcc2rs;
use libcc2rs::*;
use std::collections::BTreeMap;
use std::io::{Read, Seek, Write};
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
use std::rc::Rc;
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
assert!(((((libc::SOCK_STREAM) == (1)) as i32) != 0));
assert!(((((libc::SOCK_DGRAM) == (2)) as i32) != 0));
return 0;
}
9 changes: 9 additions & 0 deletions tests/unit/socket_type_constants.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <assert.h>
#include <sys/socket.h>
#include <sys/types.h>

int main() {
assert(SOCK_STREAM == 1);
assert(SOCK_DGRAM == 2);
return 0;
}
Loading