Skip to content
Draft
323 changes: 214 additions & 109 deletions c2rust-ast-exporter/src/AstExporter.cpp

Large diffs are not rendered by default.

21 changes: 15 additions & 6 deletions c2rust-ast-exporter/src/clang_ast.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use serde::Deserialize;
use serde_bytes::ByteBuf;
use serde_cbor::error;
use std::collections::{HashMap, VecDeque};
Expand Down Expand Up @@ -108,11 +109,18 @@ pub struct AstNode {
// Stack of macros this node was expanded from, beginning with the initial
// macro call and ending with the leaf. This needs to be a stack for nested
// macro definitions.
pub macro_expansions: Vec<u64>,
pub macro_expansion_text: Option<String>,
pub macro_invocations: Vec<MacroInvocationInfoRaw>,
pub macro_invocation_text: Option<String>,
pub extras: Vec<Value>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct MacroInvocationInfoRaw {
pub key: u32,
pub macro_id: u64,
pub parameter: Option<String>,
}

#[derive(Debug, Clone)]
pub struct TypeNode {
pub tag: TypeTag,
Expand Down Expand Up @@ -260,9 +268,10 @@ pub fn process(items: Value) -> error::Result<AstContext> {
};

// entry[10]
let macro_expansions = from_value::<Vec<u64>>(entry.pop_front().unwrap()).unwrap();
let macro_invocations =
from_value::<Vec<MacroInvocationInfoRaw>>(entry.pop_front().unwrap()).unwrap();

let macro_expansion_text = expect_opt_str(&entry.pop_front().unwrap())
let macro_invocation_text = expect_opt_str(&entry.pop_front().unwrap())
.unwrap()
.map(|s| s.to_string());

Expand All @@ -278,8 +287,8 @@ pub fn process(items: Value) -> error::Result<AstContext> {
},
type_id,
rvalue,
macro_expansions,
macro_expansion_text,
macro_invocations,
macro_invocation_text,
extras: entry.into_iter().collect(),
};

Expand Down
6 changes: 3 additions & 3 deletions c2rust-transpile/src/c_ast/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,8 +1047,8 @@ impl ConversionContext {
};

if expected_ty & EXPR != 0 {
for mac_id in &node.macro_expansions {
let mac = CDeclId(self.visit_node_type(*mac_id, MACRO_DECL));
for info in &node.macro_invocations {
let mac = CDeclId(self.visit_node_type(info.macro_id, MACRO_DECL));
self.typed_context
.macro_invocations
.entry(CExprId(new_id))
Expand All @@ -1057,7 +1057,7 @@ impl ConversionContext {
}
}

if let Some(text) = &node.macro_expansion_text {
if let Some(text) = &node.macro_invocation_text {
self.typed_context
.macro_expansion_text
.insert(CExprId(new_id), text.clone());
Expand Down
5 changes: 5 additions & 0 deletions c2rust-transpile/tests/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ fn test_lift_const() {
transpile("lift_const.c").run();
}

#[test]
fn test_macro_fns() {
transpile("macro_fns.c").run();
}

#[test]
fn test_macrocase() {
transpile("macrocase.c").run();
Expand Down
27 changes: 27 additions & 0 deletions c2rust-transpile/tests/snapshots/macro_fns.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#define CONST 42

#define ID(x) x
#define PAREN(x) (x)
#define LIT_ID ID(42)
#define LIT_PAREN PAREN(42)
#define CONST_ID ID(CONST)
#define CONST_PAREN PAREN(CONST)
#define NESTED_ID(x) ID(x)
#define NESTED_PAREN(x) PAREN(x)

void basic(void) {
int lit_id = LIT_ID;
int lit_paren = LIT_PAREN;
int const_id = CONST_ID;
int const_paren = CONST_PAREN;

int id_with_lit = ID(42);
int paren_with_lit = PAREN(42);
int id_with_const = ID(CONST);
int paren_with_const = PAREN(CONST);

int nested_id_with_lit = NESTED_ID(42);
int nested_paren_with_lit = NESTED_PAREN(42);
int nested_id_with_const = NESTED_ID(CONST);
int nested_paren_with_const = NESTED_PAREN(CONST);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
source: c2rust-transpile/tests/snapshots.rs
expression: cat tests/snapshots/macro_fns.2021.clang15.rs
---
#![allow(
clippy::missing_safety_doc,
dead_code,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
unused_assignments,
unused_mut
)]
pub const LIT_ID: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
pub const LIT_PAREN: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
pub const CONST_ID: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
pub const CONST_PAREN: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
#[no_mangle]
pub unsafe extern "C" fn basic() {
let mut lit_id: ::core::ffi::c_int = LIT_ID;
let mut lit_paren: ::core::ffi::c_int = LIT_PAREN;
let mut const_id: ::core::ffi::c_int = CONST_ID;
let mut const_paren: ::core::ffi::c_int = CONST_PAREN;
let mut id_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut paren_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut id_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut paren_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_id_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_paren_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_id_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_paren_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
source: c2rust-transpile/tests/snapshots.rs
expression: cat tests/snapshots/macro_fns.2024.clang15.rs
---
#![allow(
clippy::missing_safety_doc,
dead_code,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
unsafe_op_in_unsafe_fn,
unused_assignments,
unused_mut
)]
pub const LIT_ID: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
pub const LIT_PAREN: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
pub const CONST_ID: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
pub const CONST_PAREN: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn basic() {
let mut lit_id: ::core::ffi::c_int = LIT_ID;
let mut lit_paren: ::core::ffi::c_int = LIT_PAREN;
let mut const_id: ::core::ffi::c_int = CONST_ID;
let mut const_paren: ::core::ffi::c_int = CONST_PAREN;
let mut id_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut paren_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut id_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut paren_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_id_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_paren_with_lit: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_id_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
let mut nested_paren_with_const: ::core::ffi::c_int = 42 as ::core::ffi::c_int;
}
Loading
Loading