diff --git a/c2rust-ast-exporter/src/AstExporter.cpp b/c2rust-ast-exporter/src/AstExporter.cpp index 0126c0d6db..83b0e813d7 100644 --- a/c2rust-ast-exporter/src/AstExporter.cpp +++ b/c2rust-ast-exporter/src/AstExporter.cpp @@ -1418,65 +1418,106 @@ class TranslateASTVisitor final LLVM_DEBUG(Range.getBegin().dump(Mgr)); LLVM_DEBUG(Range.getEnd().dump(Mgr)); - auto Begin = Range.getBegin(); - auto End = Range.getEnd(); - - // Check that we are only expanding a single macro call. - if (!Begin.isMacroID() || !End.isMacroID() || - Mgr.getImmediateMacroCallerLoc(Begin) != Mgr.getImmediateMacroCallerLoc(End)) + if (!Range.getBegin().isMacroID() || !Range.getEnd().isMacroID()) { return true; + } - if (Begin.isMacroID()) { -#if CLANG_VERSION_MAJOR < 7 - // getImmediateExpansionRange in LLVM<7 returns a - // std::pair, which we need to - // translate to a CharSourceRange for Lexer::getSourceText - auto LocPair = Mgr.getImmediateExpansionRange(Begin); - auto ExpansionRange = CharSourceRange::getCharRange(LocPair.first, LocPair.second); -#else // CLANG_VERSION_MAJOR >= 7 - auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin); -#endif - curMacroExpansionSource = - Lexer::getSourceText(ExpansionRange, Mgr, Context->getLangOpts()); + // Holds the stack of ranges of macro expansions that expand to this expression. + // The last element is the top-level macro call. + auto ExpansionStack = getMacroExpansionStack(Range); + + if (ExpansionStack.empty()) { + return true; } - // The macro stack unwound by getImmediateMacroCallerLoc and friends - // starts with literal replacement and works it's way to the macro call - // that was replaced. - while (Begin.isMacroID()) { -#if CLANG_VERSION_MAJOR < 7 - auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin); - auto ExpansionBegin = ExpansionRange.first; - auto ExpansionEnd = ExpansionRange.second; -#else // CLANG_VERSION_MAJOR >= 7 - auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin).getAsRange(); - auto ExpansionBegin = ExpansionRange.getBegin(); - auto ExpansionEnd = ExpansionRange.getEnd(); -#endif + curMacroExpansionSource = + Lexer::getSourceText(ExpansionStack[0], Mgr, Context->getLangOpts()); + + for (auto &ExpansionRange : ExpansionStack) { StringRef name; - MacroInfo *mac = getMacroInfo(ExpansionBegin, name); + MacroInfo *mac = getMacroInfo(ExpansionRange.getBegin(), name); - if (!mac || mac->getNumTokens() == 0) + if (!mac || mac->getNumTokens() == 0) { return true; - auto ReplacementBegin = mac->getReplacementToken(0).getLocation(); - auto ReplacementEnd = mac->getDefinitionEndLoc(); - // Verify that this expansion covers the entire macro replacement - // definition, i.e. E is not a subexpression of the macro - // replacement. - if (Mgr.getSpellingLoc(Begin) != ReplacementBegin || - Mgr.getSpellingLoc(End) != ReplacementEnd) - return true; - - Begin = ExpansionBegin; - End = ExpansionEnd; + } - if (VisitMacro(name, Begin, mac, E)) { + if (VisitMacro(name, ExpansionRange.getBegin(), mac, E)) { curMacroExpansionStack.push_back(mac); } } + return true; } + std::vector getMacroExpansionStack(SourceRange Range) const { + auto &Mgr = Context->getSourceManager(); + auto Begin = Range.getBegin(); + auto End = Range.getEnd(); + std::vector ExpansionStack; + + do { + if (!isAtStartOfImmediateMacroExpansion(Begin)) { + break; + } + + auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin); + ExpansionStack.push_back(ExpansionRange); + Begin = ExpansionRange.getBegin(); + } while (Begin.isMacroID()); + + // Find the point at which `Begin` and `End` converge on the same expansion range. + // This is where the expression in `Range` first corresponds to a single macro call. + auto ConvergencePoint = ExpansionStack.end(); + + do { + if (!isAtEndOfImmediateMacroExpansion(End)) { + break; + } + + auto ExpansionRange = Mgr.getImmediateExpansionRange(End); + ConvergencePoint = std::find_if( + ExpansionStack.begin(), + ExpansionStack.end(), + [ExpansionRange](auto &R) { + return R.getAsRange() == ExpansionRange.getAsRange() && + R.isTokenRange() == ExpansionRange.isTokenRange(); + } + ); + End = ExpansionRange.getEnd(); + } while (End.isMacroID() && ConvergencePoint == ExpansionStack.end()); + + // Remove all elements before the convergence point. + ExpansionStack.erase(ExpansionStack.begin(), ConvergencePoint); + + // Ensure the remaining ranges still correspond to the input `Range`. + auto EraseAfter = std::find_if( + ExpansionStack.begin(), + ExpansionStack.end(), + [this](auto &R) { + auto End = R.getEnd(); + return End.isMacroID() && !isAtEndOfImmediateMacroExpansion(End); + } + ); + auto EraseFrom = EraseAfter + 1; + + if (EraseFrom < ExpansionStack.end()) { + ExpansionStack.erase(EraseFrom, ExpansionStack.end()); + } + + return ExpansionStack; + } + + bool isAtStartOfImmediateMacroExpansion(SourceLocation loc) const { + auto &Mgr = Context->getSourceManager(); + return Mgr.isAtStartOfImmediateMacroExpansion(loc); + } + + bool isAtEndOfImmediateMacroExpansion(SourceLocation loc) const { + auto &Mgr = Context->getSourceManager(); + auto spellingLoc = Mgr.getSpellingLoc(loc); + auto len = Lexer::MeasureTokenLength(spellingLoc, Mgr, Context->getLangOpts()); + return Mgr.isAtEndOfImmediateMacroExpansion(loc.getLocWithOffset(len)); + } bool VisitVAArgExpr(VAArgExpr *E) { std::vector childIds{E->getSubExpr()}; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap index 5c48974186..ae24992267 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap @@ -52,6 +52,11 @@ pub const NESTED_FLOAT: ::core::ffi::c_double = LITERAL_FLOAT; pub const NESTED_CHAR: ::core::ffi::c_int = LITERAL_CHAR; pub const NESTED_STR: [::core::ffi::c_char; 6] = LITERAL_STR; pub const NESTED_STRUCT: S = LITERAL_STRUCT; +pub const NEGATIVE_INT: ::core::ffi::c_int = -LITERAL_INT; +pub const INT_ARITHMETIC: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub const MIXED_ARITHMETIC: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double + + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double + - true_0 as ::core::ffi::c_double; pub const PARENS: ::core::ffi::c_int = NESTED_INT * (LITERAL_CHAR + true_0); pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { LITERAL_STR @@ -60,7 +65,24 @@ pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { .offset(-(3 as ::core::ffi::c_int as isize)) }; pub const WIDENING_CAST: ::core::ffi::c_ulonglong = LITERAL_INT as ::core::ffi::c_ulonglong; +pub const NARROWING_CAST: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; pub const CONVERSION_CAST: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double; +pub const INDEXING: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; +pub const STR_CONCATENATION: [::core::ffi::c_char; 18] = unsafe { + ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") +}; +pub const REF_MACRO: *const ::core::ffi::c_char = unsafe { + NESTED_STR + .as_ptr() + .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) as *const ::core::ffi::c_char +}; +pub const REF_LITERAL: *mut S = &LITERAL_STRUCT as *const S as *mut S; +pub const TERNARY: ::core::ffi::c_int = if LITERAL_BOOL != 0 { + 1 as ::core::ffi::c_int +} else { + 2 as ::core::ffi::c_int +}; +pub const MEMBER: ::core::ffi::c_int = LITERAL_STRUCT.i; #[no_mangle] pub unsafe extern "C" fn local_muts() { let mut literal_int: ::core::ffi::c_int = LITERAL_INT; @@ -87,45 +109,28 @@ pub unsafe extern "C" fn local_muts() { 3 as ::core::ffi::c_int, ]; let mut nested_struct: S = NESTED_STRUCT; - let mut negative_int: ::core::ffi::c_int = -LITERAL_INT; - let mut int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mut mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let mut int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mut mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut parens: ::core::ffi::c_int = PARENS; let mut ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let mut widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let mut narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let mut narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let mut conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let mut indexing: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - let mut str_concatenation: [::core::ffi::c_char; 18] = - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0"); + let mut indexing: ::core::ffi::c_char = INDEXING; + let mut str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let mut str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; let mut builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut ref_indexing: *const ::core::ffi::c_char = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - let mut ref_struct: *const S = &mut LITERAL_STRUCT as *mut S; - let mut ternary: ::core::ffi::c_int = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - let mut member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let mut ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let mut ref_struct: *const S = REF_LITERAL; + let mut ternary: ::core::ffi::c_int = TERNARY; + let mut member: ::core::ffi::c_int = MEMBER; let mut stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -160,43 +165,27 @@ pub unsafe extern "C" fn local_consts() { 3 as ::core::ffi::c_int, ]; let nested_struct: S = NESTED_STRUCT; - let negative_int: ::core::ffi::c_int = -LITERAL_INT; - let int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let parens: ::core::ffi::c_int = PARENS; let ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let indexing: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - let str_concatenation: [::core::ffi::c_char; 18] = - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0"); + let indexing: ::core::ffi::c_char = INDEXING; + let str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; let builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let ref_indexing: *const ::core::ffi::c_char = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - let ref_struct: *const S = &mut LITERAL_STRUCT as *mut S; - let ternary: ::core::ffi::c_int = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - let member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let ref_struct: *const S = REF_LITERAL; + let ternary: ::core::ffi::c_int = TERNARY; + let member: ::core::ffi::c_int = MEMBER; let stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -233,30 +222,25 @@ static mut global_static_const_nested_array: [::core::ffi::c_int; 3] = [ 3 as ::core::ffi::c_int, ]; static mut global_static_const_nested_struct: S = NESTED_STRUCT; -static mut global_static_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; -static mut global_static_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +static mut global_static_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; +static mut global_static_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; static mut global_static_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; static mut global_static_const_parens: ::core::ffi::c_int = PARENS; static mut global_static_const_ptr_arithmetic: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); static mut global_static_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; -static mut global_static_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +static mut global_static_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; static mut global_static_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; static mut global_static_const_indexing: ::core::ffi::c_char = 0; static mut global_static_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; -static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; + STR_CONCATENATION.as_ptr(); +static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; static mut global_static_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; static mut global_static_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); -static mut global_static_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +static mut global_static_const_ref_struct: *const S = REF_LITERAL; static mut global_static_const_ternary: ::core::ffi::c_int = 0; static mut global_static_const_member: ::core::ffi::c_int = 0; #[no_mangle] @@ -304,14 +288,12 @@ pub static mut global_const_nested_array: [::core::ffi::c_int; 3] = [ #[no_mangle] pub static mut global_const_nested_struct: S = NESTED_STRUCT; #[no_mangle] -pub static mut global_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; +pub static mut global_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; #[no_mangle] -pub static mut global_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub static mut global_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; #[no_mangle] pub static mut global_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; #[no_mangle] pub static mut global_const_parens: ::core::ffi::c_int = PARENS; #[no_mangle] @@ -320,19 +302,16 @@ pub static mut global_const_ptr_arithmetic: *const ::core::ffi::c_char = #[no_mangle] pub static mut global_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; #[no_mangle] -pub static mut global_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +pub static mut global_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; #[no_mangle] pub static mut global_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; #[no_mangle] pub static mut global_const_indexing: ::core::ffi::c_char = 0; #[no_mangle] pub static mut global_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; + STR_CONCATENATION.as_ptr(); #[no_mangle] -pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; +pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; #[no_mangle] pub static mut global_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; @@ -340,7 +319,7 @@ pub static mut global_const_builtin: ::core::ffi::c_int = pub static mut global_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); #[no_mangle] -pub static mut global_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +pub static mut global_const_ref_struct: *const S = REF_LITERAL; #[no_mangle] pub static mut global_const_ternary: ::core::ffi::c_int = 0; #[no_mangle] @@ -446,29 +425,15 @@ pub unsafe extern "C" fn late_init_var() -> ::core::ffi::c_int { } unsafe extern "C" fn c2rust_run_static_initializers() { global_static_const_ptr_arithmetic = PTR_ARITHMETIC; - global_static_const_indexing = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - global_static_const_ref_indexing = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_static_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_static_const_member = LITERAL_STRUCT.i; + global_static_const_indexing = INDEXING; + global_static_const_ref_indexing = REF_MACRO; + global_static_const_ternary = TERNARY; + global_static_const_member = MEMBER; global_const_ptr_arithmetic = PTR_ARITHMETIC; - global_const_indexing = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - global_const_ref_indexing = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_const_member = LITERAL_STRUCT.i; + global_const_indexing = INDEXING; + global_const_ref_indexing = REF_MACRO; + global_const_ternary = TERNARY; + global_const_member = MEMBER; } #[used] #[cfg_attr(target_os = "linux", link_section = ".init_array")] diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap index eec44cd385..f1094eca5e 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap @@ -52,6 +52,11 @@ pub const NESTED_FLOAT: ::core::ffi::c_double = LITERAL_FLOAT; pub const NESTED_CHAR: ::core::ffi::c_int = LITERAL_CHAR; pub const NESTED_STR: [::core::ffi::c_char; 6] = LITERAL_STR; pub const NESTED_STRUCT: S = LITERAL_STRUCT; +pub const NEGATIVE_INT: ::core::ffi::c_int = -LITERAL_INT; +pub const INT_ARITHMETIC: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub const MIXED_ARITHMETIC: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double + + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double + - true_0 as ::core::ffi::c_double; pub const PARENS: ::core::ffi::c_int = NESTED_INT * (LITERAL_CHAR + true_0); pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { LITERAL_STR @@ -60,7 +65,24 @@ pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe { .offset(-(3 as ::core::ffi::c_int as isize)) }; pub const WIDENING_CAST: ::core::ffi::c_ulonglong = LITERAL_INT as ::core::ffi::c_ulonglong; +pub const NARROWING_CAST: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; pub const CONVERSION_CAST: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double; +pub const INDEXING: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; +pub const STR_CONCATENATION: [::core::ffi::c_char; 18] = unsafe { + ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") +}; +pub const REF_MACRO: *const ::core::ffi::c_char = unsafe { + NESTED_STR + .as_ptr() + .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) as *const ::core::ffi::c_char +}; +pub const REF_LITERAL: *mut S = &LITERAL_STRUCT as *const S as *mut S; +pub const TERNARY: ::core::ffi::c_int = if LITERAL_BOOL != 0 { + 1 as ::core::ffi::c_int +} else { + 2 as ::core::ffi::c_int +}; +pub const MEMBER: ::core::ffi::c_int = LITERAL_STRUCT.i; #[unsafe(no_mangle)] pub unsafe extern "C" fn local_muts() { let mut literal_int: ::core::ffi::c_int = LITERAL_INT; @@ -87,45 +109,28 @@ pub unsafe extern "C" fn local_muts() { 3 as ::core::ffi::c_int, ]; let mut nested_struct: S = NESTED_STRUCT; - let mut negative_int: ::core::ffi::c_int = -LITERAL_INT; - let mut int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mut mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let mut int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mut mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut parens: ::core::ffi::c_int = PARENS; let mut ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let mut widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let mut narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let mut narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let mut conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let mut indexing: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - let mut str_concatenation: [::core::ffi::c_char; 18] = - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0"); + let mut indexing: ::core::ffi::c_char = INDEXING; + let mut str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let mut str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; let mut builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut ref_indexing: *const ::core::ffi::c_char = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - let mut ref_struct: *const S = &mut LITERAL_STRUCT as *mut S; - let mut ternary: ::core::ffi::c_int = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - let mut member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let mut ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let mut ref_struct: *const S = REF_LITERAL; + let mut ternary: ::core::ffi::c_int = TERNARY; + let mut member: ::core::ffi::c_int = MEMBER; let mut stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -160,43 +165,27 @@ pub unsafe extern "C" fn local_consts() { 3 as ::core::ffi::c_int, ]; let nested_struct: S = NESTED_STRUCT; - let negative_int: ::core::ffi::c_int = -LITERAL_INT; - let int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; - let mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let negative_int: ::core::ffi::c_int = NEGATIVE_INT; + let int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; + let mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let parens: ::core::ffi::c_int = PARENS; let ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC; let widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; - let narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char; + let narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; let conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; - let indexing: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; - let str_concatenation: [::core::ffi::c_char; 18] = - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0"); + let indexing: ::core::ffi::c_char = INDEXING; + let str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr(); + let str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; let builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let ref_indexing: *const ::core::ffi::c_char = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - let ref_struct: *const S = &mut LITERAL_STRUCT as *mut S; - let ternary: ::core::ffi::c_int = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - let member: ::core::ffi::c_int = LITERAL_STRUCT.i; + let ref_indexing: *const ::core::ffi::c_char = REF_MACRO; + let ref_struct: *const S = REF_LITERAL; + let ternary: ::core::ffi::c_int = TERNARY; + let member: ::core::ffi::c_int = MEMBER; let stmt_expr: ::core::ffi::c_float = ({ let mut builtin_0: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; - let mut indexing_0: ::core::ffi::c_char = - NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double - + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) - as ::core::ffi::c_float; + let mut indexing_0: ::core::ffi::c_char = INDEXING; + let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float; let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int; while i < builtin_0 { mixed += indexing_0 as ::core::ffi::c_float; @@ -233,30 +222,25 @@ static mut global_static_const_nested_array: [::core::ffi::c_int; 3] = [ 3 as ::core::ffi::c_int, ]; static mut global_static_const_nested_struct: S = NESTED_STRUCT; -static mut global_static_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; -static mut global_static_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +static mut global_static_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; +static mut global_static_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; static mut global_static_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; static mut global_static_const_parens: ::core::ffi::c_int = PARENS; static mut global_static_const_ptr_arithmetic: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); static mut global_static_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; -static mut global_static_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +static mut global_static_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; static mut global_static_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; static mut global_static_const_indexing: ::core::ffi::c_char = 0; static mut global_static_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; -static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; + STR_CONCATENATION.as_ptr(); +static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; static mut global_static_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; static mut global_static_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); -static mut global_static_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +static mut global_static_const_ref_struct: *const S = REF_LITERAL; static mut global_static_const_ternary: ::core::ffi::c_int = 0; static mut global_static_const_member: ::core::ffi::c_int = 0; #[unsafe(no_mangle)] @@ -304,14 +288,12 @@ pub static mut global_const_nested_array: [::core::ffi::c_int; 3] = [ #[unsafe(no_mangle)] pub static mut global_const_nested_struct: S = NESTED_STRUCT; #[unsafe(no_mangle)] -pub static mut global_const_negative_int: ::core::ffi::c_int = -LITERAL_INT; +pub static mut global_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT; #[unsafe(no_mangle)] -pub static mut global_const_int_arithmetic: ::core::ffi::c_int = - NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int; +pub static mut global_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC; #[unsafe(no_mangle)] pub static mut global_const_mixed_arithmetic: ::core::ffi::c_float = - (LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double - - true_0 as ::core::ffi::c_double) as ::core::ffi::c_float; + MIXED_ARITHMETIC as ::core::ffi::c_float; #[unsafe(no_mangle)] pub static mut global_const_parens: ::core::ffi::c_int = PARENS; #[unsafe(no_mangle)] @@ -320,19 +302,16 @@ pub static mut global_const_ptr_arithmetic: *const ::core::ffi::c_char = #[unsafe(no_mangle)] pub static mut global_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST; #[unsafe(no_mangle)] -pub static mut global_const_narrowing_cast: ::core::ffi::c_char = - LITERAL_INT as ::core::ffi::c_char; +pub static mut global_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST; #[unsafe(no_mangle)] pub static mut global_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST; #[unsafe(no_mangle)] pub static mut global_const_indexing: ::core::ffi::c_char = 0; #[unsafe(no_mangle)] pub static mut global_const_str_concatenation_ptr: *const ::core::ffi::c_char = - b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char; + STR_CONCATENATION.as_ptr(); #[unsafe(no_mangle)] -pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe { - ::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0") -}; +pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION; #[unsafe(no_mangle)] pub static mut global_const_builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32; @@ -340,7 +319,7 @@ pub static mut global_const_builtin: ::core::ffi::c_int = pub static mut global_const_ref_indexing: *const ::core::ffi::c_char = ::core::ptr::null::<::core::ffi::c_char>(); #[unsafe(no_mangle)] -pub static mut global_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S; +pub static mut global_const_ref_struct: *const S = REF_LITERAL; #[unsafe(no_mangle)] pub static mut global_const_ternary: ::core::ffi::c_int = 0; #[unsafe(no_mangle)] @@ -446,29 +425,15 @@ pub unsafe extern "C" fn late_init_var() -> ::core::ffi::c_int { } unsafe extern "C" fn c2rust_run_static_initializers() { global_static_const_ptr_arithmetic = PTR_ARITHMETIC; - global_static_const_indexing = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - global_static_const_ref_indexing = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_static_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_static_const_member = LITERAL_STRUCT.i; + global_static_const_indexing = INDEXING; + global_static_const_ref_indexing = REF_MACRO; + global_static_const_ternary = TERNARY; + global_static_const_member = MEMBER; global_const_ptr_arithmetic = PTR_ARITHMETIC; - global_const_indexing = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize]; - global_const_ref_indexing = NESTED_STR - .as_ptr() - .offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) - as *const ::core::ffi::c_char; - global_const_ternary = if LITERAL_BOOL != 0 { - 1 as ::core::ffi::c_int - } else { - 2 as ::core::ffi::c_int - }; - global_const_member = LITERAL_STRUCT.i; + global_const_indexing = INDEXING; + global_const_ref_indexing = REF_MACRO; + global_const_ternary = TERNARY; + global_const_member = MEMBER; } #[used] #[cfg_attr(target_os = "linux", unsafe(link_section = ".init_array"))]