diff --git a/c2rust-ast-exporter/src/AstExporter.cpp b/c2rust-ast-exporter/src/AstExporter.cpp index 3d48d24574..f8981c12a5 100644 --- a/c2rust-ast-exporter/src/AstExporter.cpp +++ b/c2rust-ast-exporter/src/AstExporter.cpp @@ -711,7 +711,7 @@ class TypeEncoder final : public TypeVisitor { class TranslateASTVisitor final : public RecursiveASTVisitor { - struct MacroExpansionInfo { + struct MacroDeclInfo { StringRef Name; }; @@ -723,13 +723,20 @@ class TranslateASTVisitor final // Mapping from SourceManager FileID to index in files DenseMap file_id_mapping; std::set> exportedTags; - std::unordered_map macros; + std::unordered_map macros; + + struct MacroInvocationInfo { + uint32_t key; + MacroInfo* macro; + StringRef parameter; + }; // This stores a raw encoding of the macro call site SourceLocation, since // SourceLocation isn't hashable. - std::unordered_set macroCallSites; - SmallVector curMacroExpansionStack; - StringRef curMacroExpansionSource; + // TODO: Can this be made to use `unordered_set` for speed? + std::set> macroCallSites; + SmallVector curMacroInvocationStack; + StringRef curMacroInvocationSource; // Returns true when a new entry is added to exportedTags bool markForExport(void *ptr, ASTEntryTag tag) { @@ -769,7 +776,7 @@ class TranslateASTVisitor final // Template required because Decl and Stmt don't share a common base class void encode_entry_raw(void *ast, ASTEntryTag tag, SourceRange loc, const QualType ty, bool rvalue, - bool isVaList, bool encodeMacroExpansions, + bool isVaList, bool encodeMacroInvocations, const std::vector &childIds, std::function extra) { if (!markForExport(ast, tag)) @@ -808,21 +815,33 @@ class TranslateASTVisitor final // 9 - Is Rvalue (only for expressions) cbor_encode_boolean(&local, rvalue); - // 10 - Macro expansion stack, starting with initial macro call and ending + // 10 - Macro invocation stack, starting with initial macro call and ending // with the innermost replacement. cbor_encoder_create_array(&local, &childEnc, - encodeMacroExpansions ? curMacroExpansionStack.size() : 0); - if (encodeMacroExpansions) { - for (auto I = curMacroExpansionStack.rbegin(), E = curMacroExpansionStack.rend(); + encodeMacroInvocations ? curMacroInvocationStack.size() : 0); + if (encodeMacroInvocations) { + for (auto I = curMacroInvocationStack.rbegin(), E = curMacroInvocationStack.rend(); I != E; ++I) { - cbor_encode_uint(&childEnc, uintptr_t(*I)); + CborEncoder expansionEnc; + cbor_encoder_create_array(&childEnc, &expansionEnc, 3); + + cbor_encode_uint(&expansionEnc, I->key); + cbor_encode_uint(&expansionEnc, uintptr_t(I->macro)); + + if (!I->parameter.empty()) { + cbor_encode_string(&expansionEnc, I->parameter.str()); + } else { + cbor_encode_null(&expansionEnc); + } + + cbor_encoder_close_container(&childEnc, &expansionEnc); } } cbor_encoder_close_container(&local, &childEnc); - // 11 - Macro expansion source string, if applicable. - if (!curMacroExpansionSource.empty()) { - cbor_encode_string(&local, curMacroExpansionSource.str()); + // 11 - Macro invocation source string, if applicable. + if (!curMacroInvocationSource.empty()) { + cbor_encode_string(&local, curMacroInvocationSource.str()); } else { cbor_encode_null(&local); } @@ -846,7 +865,7 @@ class TranslateASTVisitor final std::function extra = [](CborEncoder *) {}) { auto ty = ast->getType(); auto isVaList = false; - auto encodeMacroExpansions = true; + auto encodeMacroInvocations = true; #if CLANG_VERSION_MAJOR < 13 bool isRValue = ast->isRValue(); #else @@ -860,7 +879,7 @@ class TranslateASTVisitor final auto span = ast->getSourceRange(); expandSpanToFinalChar(span, Context); encode_entry_raw(ast, tag, span, ty, isRValue, isVaList, - encodeMacroExpansions, childIds, extra); + encodeMacroInvocations, childIds, extra); typeEncoder.VisitQualTypeOf(ty, ast); } @@ -870,11 +889,11 @@ class TranslateASTVisitor final QualType s = QualType(static_cast(nullptr), 0); auto rvalue = false; auto isVaList = false; - auto encodeMacroExpansions = false; + auto encodeMacroInvocations = false; auto span = ast->getSourceRange(); expandSpanToFinalChar(span, Context); encode_entry_raw(ast, tag, span, s, rvalue, isVaList, - encodeMacroExpansions, childIds, extra); + encodeMacroInvocations, childIds, extra); } void encode_entry( @@ -882,11 +901,11 @@ class TranslateASTVisitor final const QualType T, std::function extra = [](CborEncoder *) {}) { auto rvalue = false; - auto encodeMacroExpansions = false; + auto encodeMacroInvocations = false; auto span = ast->getSourceRange(); expandSpanToFinalChar(span, Context); encode_entry_raw(ast, tag, span, T, rvalue, - isVaList(ast, T), encodeMacroExpansions, childIds, extra); + isVaList(ast, T), encodeMacroInvocations, childIds, extra); } /// Explicitly override the source location of this decl for cases where the @@ -897,54 +916,21 @@ class TranslateASTVisitor final const std::vector &childIds, const QualType T, std::function extra = [](CborEncoder *) {}) { auto rvalue = false; - auto encodeMacroExpansions = false; + auto encodeMacroInvocations = false; expandSpanToFinalChar(loc, Context); encode_entry_raw(ast, tag, loc, T, rvalue, - isVaList(ast, T), encodeMacroExpansions, childIds, extra); + isVaList(ast, T), encodeMacroInvocations, childIds, extra); } - MacroInfo* getMacroInfo(SourceLocation loc, StringRef &name) const { - auto &Mgr = Context->getSourceManager(); - Token Result; - if (!Lexer::getRawToken(Mgr.getSpellingLoc(loc), Result, - Mgr, Context->getLangOpts(), false)) { - if (Result.is(tok::raw_identifier)) { - PP.LookUpIdentifierInfo(Result); - } - IdentifierInfo *IdentifierInfo = Result.getIdentifierInfo(); - if (IdentifierInfo && IdentifierInfo->hadMacroDefinition()) { - std::pair DecLoc = - Mgr.getDecomposedExpansionLoc(loc); - // Get the definition just before the searched location - // so that a macro referenced in a '#undef MACRO' can - // still be found. - SourceLocation BeforeSearchedLocation = - Mgr.getMacroArgExpandedLocation( - Mgr.getLocForStartOfFile(DecLoc.first) - .getLocWithOffset(DecLoc.second - 1)); - MacroDefinition MacroDef = PP.getMacroDefinitionAtLoc( - IdentifierInfo, BeforeSearchedLocation); - MacroInfo *MacroInf = MacroDef.getMacroInfo(); - if (MacroInf) { - LLVM_DEBUG(dbgs() << IdentifierInfo->getName() << "\n"); - LLVM_DEBUG(MacroInf->dump()); - LLVM_DEBUG(dbgs() << "\n"); - name = IdentifierInfo->getName(); - return MacroInf; - } - } - } - return nullptr; - } - - bool VisitMacro(StringRef name, SourceLocation loc, MacroInfo *mac, Expr *E) { + bool VisitMacro(StringRef name, StringRef parameter, SourceLocation loc, MacroInfo *mac, Expr *E) { // TODO: handle builtin macros if (mac->isBuiltinMacro()) return false; // If this isn't the first time we've seen this macro call site, we // shouldn't associate this expression with the macro as it is a subexpr // of a previously seen expression. - if (!macroCallSites.insert(loc.getRawEncoding()).second) + std::pair key { loc.getRawEncoding(), parameter }; + if (!macroCallSites.insert(key).second) return false; auto &info = macros[mac]; if (info.Name.empty()) @@ -1007,11 +993,11 @@ class TranslateASTVisitor final void encodeMacros() { // Sort macros by source location - std::vector> macro_vec( + std::vector> macro_vec( macros.begin(), macros.end()); std::sort(macro_vec.begin(), macro_vec.end(), - [](const std::pair &a, - const std::pair &b) { + [](const std::pair &a, + const std::pair &b) { return a.first->getDefinitionLoc() < b.first->getDefinitionLoc(); }); @@ -1403,8 +1389,8 @@ class TranslateASTVisitor final // bool VisitExpr(Expr *E) { - curMacroExpansionStack.clear(); - curMacroExpansionSource = StringRef(); + curMacroInvocationStack.clear(); + curMacroInvocationSource = StringRef(); // We only translate constant macro objects to Rust consts, so this // expression must be constant. @@ -1426,65 +1412,184 @@ 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 - StringRef name; - MacroInfo *mac = getMacroInfo(ExpansionBegin, name); + curMacroInvocationSource = + Lexer::getSourceText(ExpansionStack[0].range, Mgr, Context->getLangOpts()); - 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) + for (auto &elem : ExpansionStack) { + auto loc = elem.range.getBegin(); + StringRef parameter; + + if (elem.isParameter) { + auto IdentifierInfo = getIdentifierInfo(loc); + + if (!IdentifierInfo) { + return true; + } + + parameter = IdentifierInfo->getName(); + loc = Mgr.getImmediateExpansionRange(loc).getBegin(); + } + + auto IdentifierInfo = getIdentifierInfo(loc); + + if (!IdentifierInfo) { return true; + } + + auto MacroInfo = getMacroInfo(loc, IdentifierInfo); - Begin = ExpansionBegin; - End = ExpansionEnd; + if (!MacroInfo || MacroInfo->getNumTokens() == 0) { + return true; + } - if (VisitMacro(name, Begin, mac, E)) { - curMacroExpansionStack.push_back(mac); + if (VisitMacro(IdentifierInfo->getName(), parameter, loc, MacroInfo, E)) { + MacroInvocationInfo info = { loc.getRawEncoding(), MacroInfo, parameter }; + curMacroInvocationStack.push_back(info); } } + return true; } + struct ExpansionRange { + CharSourceRange range; + bool isParameter; + + bool operator== (const ExpansionRange &rhs) const { + return this->range.getAsRange() == rhs.range.getAsRange() + && this->range.isTokenRange() == rhs.range.isTokenRange() + && this->isParameter == rhs.isParameter; + } + }; + + 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; + } + + ExpansionRange elem = { + Mgr.getImmediateExpansionRange(Begin), + Mgr.isMacroArgExpansion(Begin) + }; + Begin = elem.range.getBegin(); + ExpansionStack.push_back(elem); + } 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; + } + + ExpansionRange elem = { + Mgr.getImmediateExpansionRange(End), + Mgr.isMacroArgExpansion(End) + }; + End = elem.range.getEnd(); + ConvergencePoint = std::find(ExpansionStack.begin(), ExpansionStack.end(), elem); + } 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 &elem) { + auto End = elem.range.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)); + } + + IdentifierInfo *getIdentifierInfo(SourceLocation loc) const { + auto &Mgr = Context->getSourceManager(); + Token Result; + + if (!Lexer::getRawToken( + Mgr.getSpellingLoc(loc), + Result, + Mgr, + Context->getLangOpts(), + false + )) { + if (Result.is(tok::raw_identifier)) { + PP.LookUpIdentifierInfo(Result); + } + + return Result.getIdentifierInfo(); + } + + return nullptr; + } + + MacroInfo* getMacroInfo(SourceLocation loc, IdentifierInfo *IdentifierInfo) const { + if (!IdentifierInfo->hadMacroDefinition()) { + return nullptr; + } + + auto &Mgr = Context->getSourceManager(); + std::pair DecLoc = Mgr.getDecomposedExpansionLoc(loc); + // Get the definition just before the searched location + // so that a macro referenced in a '#undef MACRO' can + // still be found. + SourceLocation BeforeSearchedLocation = Mgr.getMacroArgExpandedLocation( + Mgr.getLocForStartOfFile(DecLoc.first).getLocWithOffset(DecLoc.second - 1)); + MacroDefinition MacroDef = PP.getMacroDefinitionAtLoc( + IdentifierInfo, BeforeSearchedLocation); + MacroInfo *MacroInf = MacroDef.getMacroInfo(); + + if (!MacroInf) { + return nullptr; + } + + LLVM_DEBUG(dbgs() << IdentifierInfo->getName() << "\n"); + LLVM_DEBUG(MacroInf->dump()); + LLVM_DEBUG(dbgs() << "\n"); + + return MacroInf; + } bool VisitVAArgExpr(VAArgExpr *E) { std::vector childIds{E->getSubExpr()}; diff --git a/c2rust-ast-exporter/src/clang_ast.rs b/c2rust-ast-exporter/src/clang_ast.rs index bac54c9302..a96ee1c5cc 100644 --- a/c2rust-ast-exporter/src/clang_ast.rs +++ b/c2rust-ast-exporter/src/clang_ast.rs @@ -1,3 +1,4 @@ +use serde::Deserialize; use serde_bytes::ByteBuf; use serde_cbor::error; use std::collections::{HashMap, VecDeque}; @@ -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, - pub macro_expansion_text: Option, + pub macro_invocations: Vec, + pub macro_invocation_text: Option, pub extras: Vec, } +#[derive(Debug, Clone, Deserialize)] +pub struct MacroInvocationInfoRaw { + pub key: u32, + pub macro_id: u64, + pub parameter: Option, +} + #[derive(Debug, Clone)] pub struct TypeNode { pub tag: TypeTag, @@ -260,9 +268,10 @@ pub fn process(items: Value) -> error::Result { }; // entry[10] - let macro_expansions = from_value::>(entry.pop_front().unwrap()).unwrap(); + let macro_invocations = + from_value::>(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()); @@ -278,8 +287,8 @@ pub fn process(items: Value) -> error::Result { }, type_id, rvalue, - macro_expansions, - macro_expansion_text, + macro_invocations, + macro_invocation_text, extras: entry.into_iter().collect(), }; diff --git a/c2rust-transpile/src/c_ast/conversion.rs b/c2rust-transpile/src/c_ast/conversion.rs index 4da3d7e750..89f8f723c5 100644 --- a/c2rust-transpile/src/c_ast/conversion.rs +++ b/c2rust-transpile/src/c_ast/conversion.rs @@ -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)) @@ -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()); diff --git a/c2rust-transpile/tests/snapshots.rs b/c2rust-transpile/tests/snapshots.rs index 4f10e330ea..a2185a094c 100644 --- a/c2rust-transpile/tests/snapshots.rs +++ b/c2rust-transpile/tests/snapshots.rs @@ -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(); diff --git a/c2rust-transpile/tests/snapshots/macro_fns.c b/c2rust-transpile/tests/snapshots/macro_fns.c new file mode 100644 index 0000000000..e6a2a55284 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/macro_fns.c @@ -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); +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macro_fns.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macro_fns.c.2021.clang15.snap new file mode 100644 index 0000000000..b4120ee024 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macro_fns.c.2021.clang15.snap @@ -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; +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macro_fns.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macro_fns.c.2024.clang15.snap new file mode 100644 index 0000000000..e1ed38afc8 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macro_fns.c.2024.clang15.snap @@ -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; +} 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 b059b1a47f..3f8ff8ab44 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 @@ -58,6 +58,11 @@ pub const NESTED_CHAR: ::core::ffi::c_int = LITERAL_CHAR; pub const NESTED_STR: [::core::ffi::c_char; 6] = LITERAL_STR; pub const NESTED_ARRAY: [::core::ffi::c_int; 3] = LITERAL_ARRAY; 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 @@ -66,7 +71,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; @@ -85,45 +107,28 @@ pub unsafe extern "C" fn local_muts() { let mut nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let mut nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; 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; @@ -150,43 +155,27 @@ pub unsafe extern "C" fn local_consts() { let nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; 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; @@ -215,30 +204,25 @@ static mut global_static_const_nested_str_ptr: *const ::core::ffi::c_char = NEST static mut global_static_const_nested_str: [::core::ffi::c_char; 6] = NESTED_STR; static mut global_static_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; 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] @@ -278,14 +262,12 @@ pub static mut global_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY #[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] @@ -294,19 +276,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; @@ -314,7 +293,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] @@ -420,29 +399,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 1541727a10..2cb96b462c 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 @@ -58,6 +58,11 @@ pub const NESTED_CHAR: ::core::ffi::c_int = LITERAL_CHAR; pub const NESTED_STR: [::core::ffi::c_char; 6] = LITERAL_STR; pub const NESTED_ARRAY: [::core::ffi::c_int; 3] = LITERAL_ARRAY; 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 @@ -66,7 +71,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; @@ -85,45 +107,28 @@ pub unsafe extern "C" fn local_muts() { let mut nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let mut nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; 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; @@ -150,43 +155,27 @@ pub unsafe extern "C" fn local_consts() { let nested_str: [::core::ffi::c_char; 6] = NESTED_STR; let nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; 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; @@ -215,30 +204,25 @@ static mut global_static_const_nested_str_ptr: *const ::core::ffi::c_char = NEST static mut global_static_const_nested_str: [::core::ffi::c_char; 6] = NESTED_STR; static mut global_static_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY; 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)] @@ -278,14 +262,12 @@ pub static mut global_const_nested_array: [::core::ffi::c_int; 3] = NESTED_ARRAY #[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)] @@ -294,19 +276,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; @@ -314,7 +293,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)] @@ -420,29 +399,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"))]