diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 34e85773d..5aba7cecc 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -139,6 +139,28 @@ std::string Converter::GetUnboxedTypeAsString(clang::QualType qual_type) { return ToString(qual_type); } +std::string +Converter::GetTemplateArgumentAsString(const clang::TemplateArgument &arg) { + switch (arg.getKind()) { + case clang::TemplateArgument::Type: + return GetUnboxedTypeAsString(arg.getAsType()); + case clang::TemplateArgument::Integral: + case clang::TemplateArgument::NullPtr: + case clang::TemplateArgument::Declaration: + case clang::TemplateArgument::StructuralValue: { + auto expr = GetSema().BuildExpressionFromNonTypeTemplateArgument( + arg, clang::SourceLocation()); + assert(expr.isUsable() && "cannot build non-type template argument"); + Buffer buf(*this); + Convert(expr.get()); + return std::move(buf).str(); + } + default: + assert(0 && "template parameter is not bound to a type or a value"); + return {}; + } +} + bool Converter::ConvertMappedType(clang::QualType qual_type) { std::string type_as_string = Mapper::Map(*this, qual_type); if (type_as_string == token::kIgnoreRule) { @@ -747,6 +769,10 @@ bool Converter::IsPassThroughRule(clang::Expr *expr) const { } bool Converter::RecordDerivesCopy(const clang::RecordDecl *decl) { + if (auto cxx = llvm::dyn_cast(decl); + cxx && cxx->isLambda()) { + return false; + } if (auto rule = RuleRegistry::Search(ctx_, ctx_.getCanonicalTagType(decl)).first) { auto &derives = rule->type_info.derives; diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 2bc85cb91..28fa6ed71 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -63,6 +63,8 @@ class Converter : public clang::RecursiveASTVisitor { virtual std::string GetUnboxedTypeAsString(clang::QualType qual_type); + std::string GetTemplateArgumentAsString(const clang::TemplateArgument &arg); + bool VisitRecoveryExpr(clang::RecoveryExpr *expr); virtual void EmitFilePreamble(); diff --git a/cpp2rust/converter/printer.cpp b/cpp2rust/converter/printer.cpp index a4d2874c4..384aef9b3 100644 --- a/cpp2rust/converter/printer.cpp +++ b/cpp2rust/converter/printer.cpp @@ -8,10 +8,8 @@ #include #include -#include #include #include -#include #include #include @@ -78,24 +76,6 @@ clang::QualType normalizeQualType(clang::ASTContext &ctx, ctx); } -std::string normalizeTranslationRule(std::string rule) { - // Detach pointer from double reference. Useful for matching translation - // rules. - ReplaceAll(rule, "*&&", "* &&"); - - static const std::array, 1> - normalization_rules{{ - // Ignore constant template parameters, i.e. replace them with _. - {std::regex(R"(\b\d+\b)"), "_"}, - }}; - - for (const auto &r : normalization_rules) { - rule = std::regex_replace(rule, r.first, r.second); - } - - return rule; -} - } // namespace std::string ToRustName(std::string name) { @@ -171,7 +151,7 @@ std::string ToString(clang::ASTContext &ctx, clang::QualType qual_type, std::string out; llvm::raw_string_ostream os(out); ctx.getPointerType(pointee).print(os, getPrintPolicy(ctx)); - return normalizeTranslationRule(std::move(out)); + return out; } } @@ -200,7 +180,7 @@ std::string ToString(clang::ASTContext &ctx, clang::QualType qual_type, std::string type; llvm::raw_string_ostream os(type); normalizeQualType(ctx, qual_type).print(os, getPrintPolicy(ctx)); - return normalizeTranslationRule(std::move(type)); + return type; } std::string ToString(clang::ASTContext &ctx, const clang::NamedDecl *decl) { @@ -237,7 +217,7 @@ std::string ToString(clang::ASTContext &ctx, const clang::NamedDecl *decl) { if (!func_decl) { decl->printQualifiedName(os, getPrintPolicy(ctx)); - return normalizeTranslationRule(std::move(out)); + return out; } os << ToString(ctx, func_decl->getReturnType()) << ' '; @@ -324,7 +304,7 @@ std::string ToString(clang::ASTContext &ctx, const clang::NamedDecl *decl) { } } - return normalizeTranslationRule(std::move(out)); + return out; } std::string ToString(clang::ASTContext &ctx, const clang::Expr *expr) { diff --git a/cpp2rust/converter/rules/matcher.cpp b/cpp2rust/converter/rules/matcher.cpp index 7d79dcedb..7fd2ff12a 100644 --- a/cpp2rust/converter/rules/matcher.cpp +++ b/cpp2rust/converter/rules/matcher.cpp @@ -12,22 +12,20 @@ namespace cpp2rust::Matcher { std::string MapBinding(Converter &converter, const Bindings &bindings, unsigned n) { - auto type = bindings.at(n); - assert(!type.isNull() && "template parameter is not bound to a type"); - return converter.GetUnboxedTypeAsString(type); + return converter.GetTemplateArgumentAsString(bindings.at(n)); } -// Substitutes concrete types into a target template string using the provided -// type mapping. Each template parameter in `tgt_template` is replaced with its -// corresponding instantiated type from `types`. +// Substitutes template arguments into a target template string. Each template +// parameter in `tgt_template` is replaced with its corresponding argument from +// `bindings`, which is either a type or a value. // // Example: -// types = { int } -// tgt_template = "Vec" -// result = "Vec" -std::string InstantiateTgt(Converter &converter, const Bindings &types, +// bindings = { int, 4 } +// tgt_template = "[T1; T2]" +// result = "[i32; 4_usize]" +std::string InstantiateTgt(Converter &converter, const Bindings &bindings, const std::string &tgt_template) { - assert(types.size() <= TranslationRule::kMaxGenerics && + assert(bindings.size() <= TranslationRule::kMaxGenerics && "template placeholder exceeds kMaxGenerics"); std::string instantiated_template = tgt_template; std::string::size_type pos = 0; @@ -40,7 +38,7 @@ std::string InstantiateTgt(Converter &converter, const Bindings &types, continue; } auto repl = - MapBinding(converter, types, instantiated_template[pos + 1] - '1'); + MapBinding(converter, bindings, instantiated_template[pos + 1] - '1'); instantiated_template.replace(pos, 2, repl); pos += repl.length(); } diff --git a/cpp2rust/converter/rules/matcher.h b/cpp2rust/converter/rules/matcher.h index 9730e8e0c..2b82100b6 100644 --- a/cpp2rust/converter/rules/matcher.h +++ b/cpp2rust/converter/rules/matcher.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -19,13 +19,13 @@ class Converter; } namespace cpp2rust::Matcher { -using Bindings = std::vector; +using Bindings = std::vector; template using Match = std::pair; std::string MapBinding(Converter &converter, const Bindings &bindings, unsigned n); -std::string InstantiateTgt(Converter &converter, const Bindings &types, +std::string InstantiateTgt(Converter &converter, const Bindings &bindings, const std::string &tgt_template); } // namespace cpp2rust::Matcher diff --git a/cpp2rust/converter/rules/registry.cpp b/cpp2rust/converter/rules/registry.cpp index 4cbd5fcf2..c4aabadcc 100644 --- a/cpp2rust/converter/rules/registry.cpp +++ b/cpp2rust/converter/rules/registry.cpp @@ -265,11 +265,11 @@ Matcher::Bindings getBindings(const clang::NamedDecl *rule, auto name = params->getParam(i)->getName(); unsigned n = 0; if (!name.consume_front("T") || name.getAsInteger(10, n) || - args[i].getKind() != clang::TemplateArgument::Type) { + args[i].getKind() == clang::TemplateArgument::Pack) { continue; } bindings.resize(std::max(bindings.size(), n)); - bindings[n - 1] = args[i].getAsType(); + bindings[n - 1] = args[i]; } return bindings; } diff --git a/cpp2rust/converter/rules/rules_loader.cpp b/cpp2rust/converter/rules/rules_loader.cpp index 044a389d3..1373ce9da 100644 --- a/cpp2rust/converter/rules/rules_loader.cpp +++ b/cpp2rust/converter/rules/rules_loader.cpp @@ -237,6 +237,8 @@ class RuleUsageCollector case clang::TemplateArgument::Null: case clang::TemplateArgument::Integral: case clang::TemplateArgument::NullPtr: + case clang::TemplateArgument::Declaration: + case clang::TemplateArgument::StructuralValue: case clang::TemplateArgument::Expression: case clang::TemplateArgument::Template: break; diff --git a/rules/pair/src.cpp b/rules/pair/src.cpp index 103a79970..508e96f77 100644 --- a/rules/pair/src.cpp +++ b/rules/pair/src.cpp @@ -48,3 +48,19 @@ template const T2 &f15(const std::pair &a0) { template const T1 &f16(const std::pair &a0) { return a0.first; } + +template T1 &f17(std::pair &a0) { + return std::get<0>(a0); +} + +template T2 &f18(std::pair &a0) { + return std::get<1>(a0); +} + +template const T1 &f19(const std::pair &a0) { + return std::get<0>(a0); +} + +template const T2 &f20(const std::pair &a0) { + return std::get<1>(a0); +} diff --git a/rules/pair/tgt_refcount.rs b/rules/pair/tgt_refcount.rs index 0078956c5..5cfff3711 100644 --- a/rules/pair/tgt_refcount.rs +++ b/rules/pair/tgt_refcount.rs @@ -68,3 +68,19 @@ fn f15(a0: (Value, Value)) -> Value { fn f16(a0: (Value, Value)) -> Value { a0.0 } + +fn f17(a0: (Value, Value)) -> Ptr { + a0.0.as_pointer() +} + +fn f18(a0: (Value, Value)) -> Ptr { + a0.1.as_pointer() +} + +fn f19(a0: (Value, Value)) -> Ptr { + a0.0.as_pointer() +} + +fn f20(a0: (Value, Value)) -> Ptr { + a0.1.as_pointer() +} diff --git a/rules/pair/tgt_unsafe.rs b/rules/pair/tgt_unsafe.rs index 9bf460bd8..d679f6594 100644 --- a/rules/pair/tgt_unsafe.rs +++ b/rules/pair/tgt_unsafe.rs @@ -37,3 +37,19 @@ unsafe fn f15(a0: (T1, T2)) -> T2 { unsafe fn f16(a0: (T1, T2)) -> T1 { a0.0 } + +unsafe fn f17(a0: &mut (T1, T2)) -> *mut T1 { + &mut a0.0 +} + +unsafe fn f18(a0: &mut (T1, T2)) -> *mut T2 { + &mut a0.1 +} + +unsafe fn f19(a0: &(T1, T2)) -> *const T1 { + &a0.0 +} + +unsafe fn f20(a0: &(T1, T2)) -> *const T2 { + &a0.1 +} diff --git a/tests/unit/lambda_as_field.cpp b/tests/unit/lambda_as_field.cpp index 48ddeda96..a0a37ab14 100644 --- a/tests/unit/lambda_as_field.cpp +++ b/tests/unit/lambda_as_field.cpp @@ -1,6 +1,4 @@ // ADDITIONAL_COMPILE_FLAGS: -std=c++23 -// no-compile -// Blocked by https://github.com/Cpp2Rust/cpp2rust/issues/435 #include #include diff --git a/tests/unit/lambda_decltype_type.cpp b/tests/unit/lambda_decltype_type.cpp index 05b946a6d..45b03f791 100644 --- a/tests/unit/lambda_decltype_type.cpp +++ b/tests/unit/lambda_decltype_type.cpp @@ -1,6 +1,4 @@ // ADDITIONAL_COMPILE_FLAGS: -std=c++23 -// no-compile -// Blocked by https://github.com/Cpp2Rust/cpp2rust/issues/435 #include template struct Sorted { diff --git a/tests/unit/nttp_distinct_specializations.cpp b/tests/unit/nttp_distinct_specializations.cpp new file mode 100644 index 000000000..5bb406211 --- /dev/null +++ b/tests/unit/nttp_distinct_specializations.cpp @@ -0,0 +1,30 @@ +#include + +template struct S { + int v; + int get() const { return v * N; } +}; + +template <> struct S<2> { + int v; + int w; + int get() const { return v - w; } +}; + +template int scale(int x) { return x * N; } + +template <> int scale<2>(int x) { return x - 2; } + +int main() { + S<1> s1{5}; + S<2> s2{5, 1}; + S<3> s3{5}; + assert(s1.get() == 5); + assert(s2.get() == 4); + assert(s3.get() == 15); + + assert(scale<1>(7) == 7); + assert(scale<2>(7) == 5); + assert(scale<3>(7) == 21); + return 0; +} diff --git a/tests/unit/out/refcount/lambda_as_field.rs b/tests/unit/out/refcount/lambda_as_field.rs index e2087334d..4507fd71f 100644 --- a/tests/unit/out/refcount/lambda_as_field.rs +++ b/tests/unit/out/refcount/lambda_as_field.rs @@ -8,15 +8,15 @@ use std::os::fd::AsFd; use std::rc::{Rc, Weak}; #[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Destructor)] #[byte_size(1)] -pub struct Guard__lambda_at_lambda_as_field_cpp______ { +pub struct Guard__lambda_at_lambda_as_field_cpp_34_13__ { #[offset(0)] #[byte_size(1)] pub f: FnPtr, } -impl Default for Guard__lambda_at_lambda_as_field_cpp______ { +impl Default for Guard__lambda_at_lambda_as_field_cpp_34_13__ { fn default() -> Self { { - Guard__lambda_at_lambda_as_field_cpp______ { + Guard__lambda_at_lambda_as_field_cpp_34_13__ { f: FnPtr::::new(|| { (*count_0.with(Value::clone).borrow_mut()).postfix_inc(); }), @@ -24,19 +24,26 @@ impl Default for Guard__lambda_at_lambda_as_field_cpp______ { } } } +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Destructor, Default)] +#[byte_size(8)] +pub struct Guard__lambda_at_lambda_as_field_cpp_45_13__ { + #[offset(0)] + #[byte_size(8)] + pub f: FnPtr, +} #[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg)] #[byte_size(8)] -pub struct Holder__lambda_at_lambda_as_field_cpp______ { +pub struct Holder__lambda_at_lambda_as_field_cpp_39_12__ { #[offset(0)] #[byte_size(1)] pub f: FnPtr i32>, #[offset(4)] pub calls: i32, } -impl Default for Holder__lambda_at_lambda_as_field_cpp______ { +impl Default for Holder__lambda_at_lambda_as_field_cpp_39_12__ { fn default() -> Self { { - Holder__lambda_at_lambda_as_field_cpp______ { + Holder__lambda_at_lambda_as_field_cpp_39_12__ { f: FnPtr:: i32>::new(|mut x: i32| -> i32 { { return (x + 1); @@ -47,16 +54,25 @@ impl Default for Holder__lambda_at_lambda_as_field_cpp______ { } } } +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Default)] +#[byte_size(8)] +pub struct Holder__lambda_at_lambda_as_field_cpp_51_12__ { + #[offset(0)] + #[byte_size(4)] + pub f: FnPtr i32>, + #[offset(4)] + pub calls: i32, +} #[derive(Record, ByteRepr, FnPtrArg, MoveCtor)] #[byte_size(8)] -pub struct Moving__lambda_at_lambda_as_field_cpp______ { +pub struct Moving__lambda_at_lambda_as_field_cpp_64_12__ { #[offset(0)] #[byte_size(1)] pub f: FnPtr i32>, #[offset(4)] pub moves: i32, } -impl Moving__lambda_at_lambda_as_field_cpp______ { +impl Moving__lambda_at_lambda_as_field_cpp_64_12__ { pub fn new(f: FnPtr i32>) -> Self { let f: Value i32>> = Rc::new(RefCell::new(f)); Self { @@ -64,17 +80,17 @@ impl Moving__lambda_at_lambda_as_field_cpp______ { moves: 0, } } - pub fn move_from(o: Ptr) -> Self { + pub fn move_from(o: Ptr) -> Self { Self { f: (*o.upgrade().deref()).f.move_from(), moves: (o.with(|__s| __s.moves) + 1), } } } -impl Default for Moving__lambda_at_lambda_as_field_cpp______ { +impl Default for Moving__lambda_at_lambda_as_field_cpp_64_12__ { fn default() -> Self { { - Moving__lambda_at_lambda_as_field_cpp______ { + Moving__lambda_at_lambda_as_field_cpp_64_12__ { f: FnPtr:: i32>::new(|mut x: i32| -> i32 { { return (x * 2); @@ -118,8 +134,8 @@ pub fn main() { } fn main_0() -> i32 { { - let g: Value = - Rc::new(RefCell::new(Guard__lambda_at_lambda_as_field_cpp______ { + let g: Value = + Rc::new(RefCell::new(Guard__lambda_at_lambda_as_field_cpp_34_13__ { f: FnPtr::::new(|| { (*count_0.with(Value::clone).borrow_mut()).postfix_inc(); }), @@ -128,23 +144,24 @@ fn main_0() -> i32 { assert!((count_0.with(|rc| *rc.borrow()) == 0)); } assert!((count_0.with(|rc| *rc.borrow()) == 1)); - let n: Value = - Rc::new(RefCell::new(Holder__lambda_at_lambda_as_field_cpp______ { + let n: Value = Rc::new(RefCell::new( + Holder__lambda_at_lambda_as_field_cpp_39_12__ { f: FnPtr:: i32>::new(|mut x: i32| -> i32 { { return (x + 1); } }), calls: 0, - })); + }, + )); assert!( - (({ Holder__lambda_at_lambda_as_field_cpp______Impl::call(&n.as_pointer(), 2,) }) == 3) + (({ Holder__lambda_at_lambda_as_field_cpp_39_12__Impl::call(&n.as_pointer(), 2,) }) == 3) ); assert!(({ (*n.borrow()).calls } == 1)); let cleaned: Value = Rc::new(RefCell::new(0)); { - let g: Value = - Rc::new(RefCell::new(Guard__lambda_at_lambda_as_field_cpp______ { + let g: Value = + Rc::new(RefCell::new(Guard__lambda_at_lambda_as_field_cpp_45_13__ { f: lambda!( { let cleaned: Ptr = cleaned.as_pointer(); @@ -159,8 +176,8 @@ fn main_0() -> i32 { } assert!(((*cleaned.borrow()) == 1)); let factor: Value = Rc::new(RefCell::new(3)); - let h: Value = - Rc::new(RefCell::new(Holder__lambda_at_lambda_as_field_cpp______ { + let h: Value = Rc::new(RefCell::new( + Holder__lambda_at_lambda_as_field_cpp_51_12__ { f: lambda!( { let factor: Value = Rc::new(RefCell::new((*factor.borrow()))); @@ -170,13 +187,14 @@ fn main_0() -> i32 { } ), calls: 0, - })); + }, + )); (*factor.borrow_mut()) = 100; assert!( - (({ Holder__lambda_at_lambda_as_field_cpp______Impl::call(&h.as_pointer(), 2,) }) == 6) + (({ Holder__lambda_at_lambda_as_field_cpp_51_12__Impl::call(&h.as_pointer(), 2,) }) == 6) ); assert!( - (({ Holder__lambda_at_lambda_as_field_cpp______Impl::call(&h.as_pointer(), 5,) }) == 15) + (({ Holder__lambda_at_lambda_as_field_cpp_51_12__Impl::call(&h.as_pointer(), 5,) }) == 15) ); assert!(({ (*h.borrow()).calls } == 2)); let w: Value i32>> = Rc::new(RefCell::new( @@ -196,8 +214,8 @@ fn main_0() -> i32 { let ww: Value i32>> = Rc::new(RefCell::new(({ wrap_2((*w.borrow()).copy_from()) }))); assert!((({ (*ww.borrow()).call(2,) }) == 202)); - let m: Value = Rc::new(RefCell::new( - Moving__lambda_at_lambda_as_field_cpp______::new({ + let m: Value = Rc::new(RefCell::new( + Moving__lambda_at_lambda_as_field_cpp_64_12__::new({ FnPtr:: i32>::new(|mut x: i32| -> i32 { { return (x * 2); @@ -205,36 +223,50 @@ fn main_0() -> i32 { }) }), )); - let m2: Value = Rc::new(RefCell::new( - Moving__lambda_at_lambda_as_field_cpp______::move_from({ m.as_pointer() }), + let m2: Value = Rc::new(RefCell::new( + Moving__lambda_at_lambda_as_field_cpp_64_12__::move_from({ m.as_pointer() }), )); assert!((({ (*m2.borrow()).f.call(3,) }) == 6)); assert!(({ (*m2.borrow()).moves } == 1)); return 0; } -pub trait Guard__lambda_at_lambda_as_field_cpp______Impl { +pub trait Guard__lambda_at_lambda_as_field_cpp_34_13__Impl { fn destructor(&self); } -impl Guard__lambda_at_lambda_as_field_cpp______Impl - for Ptr +impl Guard__lambda_at_lambda_as_field_cpp_34_13__Impl + for Ptr { fn destructor(&self) { ({ (*(*self).upgrade().deref()).f.call() }); } +} +pub trait Guard__lambda_at_lambda_as_field_cpp_45_13__Impl { + fn destructor(&self); +} +impl Guard__lambda_at_lambda_as_field_cpp_45_13__Impl + for Ptr +{ fn destructor(&self) { ({ (*(*self).upgrade().deref()).f.call() }); } } -pub trait Holder__lambda_at_lambda_as_field_cpp______Impl { +pub trait Holder__lambda_at_lambda_as_field_cpp_39_12__Impl { fn call(&self, x: i32) -> i32; } -impl Holder__lambda_at_lambda_as_field_cpp______Impl - for Ptr +impl Holder__lambda_at_lambda_as_field_cpp_39_12__Impl + for Ptr { fn call(&self, mut x: i32) -> i32 { field!((*self), calls).with_mut(|__v| __v.postfix_inc()); return ({ (*(*self).upgrade().deref()).f.call(x) }); } +} +pub trait Holder__lambda_at_lambda_as_field_cpp_51_12__Impl { + fn call(&self, x: i32) -> i32; +} +impl Holder__lambda_at_lambda_as_field_cpp_51_12__Impl + for Ptr +{ fn call(&self, mut x: i32) -> i32 { field!((*self), calls).with_mut(|__v| __v.postfix_inc()); return ({ (*(*self).upgrade().deref()).f.call(x) }); diff --git a/tests/unit/out/refcount/lambda_decltype_type.rs b/tests/unit/out/refcount/lambda_decltype_type.rs index 72b906d4a..823c2e3bf 100644 --- a/tests/unit/out/refcount/lambda_decltype_type.rs +++ b/tests/unit/out/refcount/lambda_decltype_type.rs @@ -8,7 +8,7 @@ use std::os::fd::AsFd; use std::rc::{Rc, Weak}; #[derive(DeepClone, Record, ByteRepr, VaArg, FnPtrArg)] #[byte_size(24)] -pub struct Sorted__lambda_at_lambda_decltype_type_cpp______ { +pub struct Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ { #[offset(0)] #[byte_size(16)] pub items: Value>, @@ -18,10 +18,10 @@ pub struct Sorted__lambda_at_lambda_decltype_type_cpp______ { #[byte_size(1)] pub cmp: FnPtr bool>, } -impl Default for Sorted__lambda_at_lambda_decltype_type_cpp______ { +impl Default for Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ { fn default() -> Self { { - Sorted__lambda_at_lambda_decltype_type_cpp______ { + Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ { items: Rc::new(RefCell::new((0..4).map(|_| 0_i32).collect::>())), size: 0, cmp: FnPtr:: bool>::new(|mut a: i32, mut b: i32| -> bool { @@ -33,6 +33,33 @@ impl Default for Sorted__lambda_at_lambda_decltype_type_cpp______ { } } } +#[derive(DeepClone, Record, ByteRepr, VaArg, FnPtrArg)] +#[byte_size(24)] +pub struct Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ { + #[offset(0)] + #[byte_size(16)] + pub items: Value>, + #[offset(16)] + pub size: i32, + #[offset(20)] + #[byte_size(1)] + pub cmp: FnPtr bool>, +} +impl Default for Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ { + fn default() -> Self { + { + Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ { + items: Rc::new(RefCell::new((0..4).map(|_| 0_i32).collect::>())), + size: 0, + cmp: FnPtr:: bool>::new(|mut a: i32, mut b: i32| -> bool { + { + return (a < b); + } + }), + } + } + } +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -46,12 +73,12 @@ fn main_0() -> i32 { } }, ))); - let desc: Value = Rc::new(RefCell::new( - ::default(), + let desc: Value = Rc::new(RefCell::new( + ::default(), )); - ({ Sorted__lambda_at_lambda_decltype_type_cpp______Impl::insert(&desc.as_pointer(), 2) }); - ({ Sorted__lambda_at_lambda_decltype_type_cpp______Impl::insert(&desc.as_pointer(), 7) }); - ({ Sorted__lambda_at_lambda_decltype_type_cpp______Impl::insert(&desc.as_pointer(), 4) }); + ({ Sorted__lambda_at_lambda_decltype_type_cpp_22_18__Impl::insert(&desc.as_pointer(), 2) }); + ({ Sorted__lambda_at_lambda_decltype_type_cpp_22_18__Impl::insert(&desc.as_pointer(), 7) }); + ({ Sorted__lambda_at_lambda_decltype_type_cpp_22_18__Impl::insert(&desc.as_pointer(), 4) }); assert!( ((elem!( (array_field_ptr!(desc.as_pointer(), items) as Ptr::), @@ -76,12 +103,12 @@ fn main_0() -> i32 { .read()) == 2) ); - let asc: Value = Rc::new(RefCell::new( - ::default(), + let asc: Value = Rc::new(RefCell::new( + ::default(), )); - ({ Sorted__lambda_at_lambda_decltype_type_cpp______Impl::insert(&asc.as_pointer(), 2) }); - ({ Sorted__lambda_at_lambda_decltype_type_cpp______Impl::insert(&asc.as_pointer(), 7) }); - ({ Sorted__lambda_at_lambda_decltype_type_cpp______Impl::insert(&asc.as_pointer(), 4) }); + ({ Sorted__lambda_at_lambda_decltype_type_cpp_19_23__Impl::insert(&asc.as_pointer(), 2) }); + ({ Sorted__lambda_at_lambda_decltype_type_cpp_19_23__Impl::insert(&asc.as_pointer(), 7) }); + ({ Sorted__lambda_at_lambda_decltype_type_cpp_19_23__Impl::insert(&asc.as_pointer(), 4) }); assert!(((elem!((array_field_ptr!(asc.as_pointer(), items) as Ptr::), 0).read()) == 2)); assert!(((elem!((array_field_ptr!(asc.as_pointer(), items) as Ptr::), 1).read()) == 4)); assert!(((elem!((array_field_ptr!(asc.as_pointer(), items) as Ptr::), 2).read()) == 7)); @@ -116,11 +143,11 @@ fn main_0() -> i32 { assert!((({ (*less.borrow()).call(1, 3,) }) as bool)); return 0; } -pub trait Sorted__lambda_at_lambda_decltype_type_cpp______Impl { +pub trait Sorted__lambda_at_lambda_decltype_type_cpp_19_23__Impl { fn insert(&self, v: i32); } -impl Sorted__lambda_at_lambda_decltype_type_cpp______Impl - for Ptr +impl Sorted__lambda_at_lambda_decltype_type_cpp_19_23__Impl + for Ptr { fn insert(&self, mut v: i32) { let mut i: i32 = (*self).with(|__s| __s.size); @@ -139,6 +166,13 @@ impl Sorted__lambda_at_lambda_decltype_type_cpp______Impl elem!((array_field_ptr!((*self), items) as Ptr::), i).write(v); field!((*self), size).with_mut(|__v| __v.postfix_inc()); } +} +pub trait Sorted__lambda_at_lambda_decltype_type_cpp_22_18__Impl { + fn insert(&self, v: i32); +} +impl Sorted__lambda_at_lambda_decltype_type_cpp_22_18__Impl + for Ptr +{ fn insert(&self, mut v: i32) { let mut i: i32 = (*self).with(|__s| __s.size); 'loop_: while (i > 0) diff --git a/tests/unit/out/refcount/nttp_distinct_specializations.rs b/tests/unit/out/refcount/nttp_distinct_specializations.rs new file mode 100644 index 000000000..c96a166f8 --- /dev/null +++ b/tests/unit/out/refcount/nttp_distinct_specializations.rs @@ -0,0 +1,78 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Default)] +#[byte_size(8)] +pub struct S_2_ { + #[offset(0)] + pub v: i32, + #[offset(4)] + pub w: i32, +} +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Default)] +#[byte_size(4)] +pub struct S_1_ { + #[offset(0)] + pub v: i32, +} +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Default)] +#[byte_size(4)] +pub struct S_3_ { + #[offset(0)] + pub v: i32, +} +pub fn scale_0(mut x: i32) -> i32 { + return (x * 1); +} +pub fn scale_1(mut x: i32) -> i32 { + return (x * 3); +} +pub fn scale_2(mut x: i32) -> i32 { + return (x - 2); +} +pub fn main() { + __cpp2rust_init_globals(); + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let s1: Value = Rc::new(RefCell::new(S_1_ { v: 5 })); + let s2: Value = Rc::new(RefCell::new(S_2_ { v: 5, w: 1 })); + let s3: Value = Rc::new(RefCell::new(S_3_ { v: 5 })); + assert!((({ S_1_Impl::get(&s1.as_pointer(),) }) == 5)); + assert!((({ S_2_Impl::get(&s2.as_pointer(),) }) == 4)); + assert!((({ S_3_Impl::get(&s3.as_pointer(),) }) == 15)); + assert!((({ scale_0(7,) }) == 7)); + assert!((({ scale_2(7,) }) == 5)); + assert!((({ scale_1(7,) }) == 21)); + return 0; +} +pub trait S_1_Impl { + fn get(&self) -> i32; +} +impl S_1_Impl for Ptr { + fn get(&self) -> i32 { + return ((*self).with(|__s| __s.v) * 1); + } +} +pub trait S_2_Impl { + fn get(&self) -> i32; +} +impl S_2_Impl for Ptr { + fn get(&self) -> i32 { + return ((*self).with(|__s| __s.v) - (*self).with(|__s| __s.w)); + } +} +pub trait S_3_Impl { + fn get(&self) -> i32; +} +impl S_3_Impl for Ptr { + fn get(&self) -> i32 { + return ((*self).with(|__s| __s.v) * 3); + } +} +pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/refcount/pair_get.rs b/tests/unit/out/refcount/pair_get.rs new file mode 100644 index 000000000..dc4d45cfd --- /dev/null +++ b/tests/unit/out/refcount/pair_get.rs @@ -0,0 +1,30 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn second_of_0(p: Ptr<(Value, Value)>) -> i32 { + return ((*p.upgrade().deref()).1.as_pointer().read()); +} +pub fn first_of_1(p: Ptr<(Value, Value)>) -> f64 { + return ((*p.upgrade().deref()).0.as_pointer().read()); +} +pub fn main() { + __cpp2rust_init_globals(); + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let p: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(1.5_f64.try_into().expect("failed conversion"))), + Rc::new(RefCell::new(2.try_into().expect("failed conversion"))), + ))); + assert!((((*p.borrow()).0.as_pointer().read()) == 1.5_f64)); + assert!((((*p.borrow()).1.as_pointer().read()) == 2)); + assert!((({ first_of_1(p.as_pointer(),) }) == 1.5_f64)); + assert!((({ second_of_0(p.as_pointer(),) }) == 2)); + return 0; +} +pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/lambda_as_field.rs b/tests/unit/out/unsafe/lambda_as_field.rs index d6e589f5e..cde749b37 100644 --- a/tests/unit/out/unsafe/lambda_as_field.rs +++ b/tests/unit/out/unsafe/lambda_as_field.rs @@ -8,18 +8,18 @@ use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; #[repr(C)] #[derive(Clone, VaArg, FnPtrArg, DestructorUnsafe)] -pub struct Guard__lambda_at_lambda_as_field_cpp______ { +pub struct Guard__lambda_at_lambda_as_field_cpp_34_13__ { pub f: FnPtr, } -impl Guard__lambda_at_lambda_as_field_cpp______ { +impl Guard__lambda_at_lambda_as_field_cpp_34_13__ { pub unsafe fn destructor(&mut self) { (unsafe { self.f.call() }); } } -impl Default for Guard__lambda_at_lambda_as_field_cpp______ { +impl Default for Guard__lambda_at_lambda_as_field_cpp_34_13__ { fn default() -> Self { unsafe { - Guard__lambda_at_lambda_as_field_cpp______ { + Guard__lambda_at_lambda_as_field_cpp_34_13__ { f: FnPtr::::new(|| unsafe { (*std::cell::LazyCell::force_mut(&mut *&raw mut count_0)).postfix_inc(); }), @@ -27,27 +27,32 @@ impl Default for Guard__lambda_at_lambda_as_field_cpp______ { } } } -impl Guard__lambda_at_lambda_as_field_cpp______ { +#[repr(C)] +#[derive(Clone, VaArg, FnPtrArg, DestructorUnsafe, Default)] +pub struct Guard__lambda_at_lambda_as_field_cpp_45_13__ { + pub f: FnPtr, +} +impl Guard__lambda_at_lambda_as_field_cpp_45_13__ { pub unsafe fn destructor(&mut self) { (unsafe { self.f.call() }); } } #[repr(C)] #[derive(Clone, VaArg, FnPtrArg)] -pub struct Holder__lambda_at_lambda_as_field_cpp______ { +pub struct Holder__lambda_at_lambda_as_field_cpp_39_12__ { pub f: FnPtr i32>, pub calls: i32, } -impl Holder__lambda_at_lambda_as_field_cpp______ { +impl Holder__lambda_at_lambda_as_field_cpp_39_12__ { pub unsafe fn call(&mut self, mut x: i32) -> i32 { self.calls.postfix_inc(); return (unsafe { self.f.call(x) }); } } -impl Default for Holder__lambda_at_lambda_as_field_cpp______ { +impl Default for Holder__lambda_at_lambda_as_field_cpp_39_12__ { fn default() -> Self { unsafe { - Holder__lambda_at_lambda_as_field_cpp______ { + Holder__lambda_at_lambda_as_field_cpp_39_12__ { f: FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) + (1)); @@ -58,7 +63,13 @@ impl Default for Holder__lambda_at_lambda_as_field_cpp______ { } } } -impl Holder__lambda_at_lambda_as_field_cpp______ { +#[repr(C)] +#[derive(Clone, VaArg, FnPtrArg, Default)] +pub struct Holder__lambda_at_lambda_as_field_cpp_51_12__ { + pub f: FnPtr i32>, + pub calls: i32, +} +impl Holder__lambda_at_lambda_as_field_cpp_51_12__ { pub unsafe fn call(&mut self, mut x: i32) -> i32 { self.calls.postfix_inc(); return (unsafe { self.f.call(x) }); @@ -66,11 +77,11 @@ impl Holder__lambda_at_lambda_as_field_cpp______ { } #[repr(C)] #[derive(FnPtrArg, MoveCtorUnsafe)] -pub struct Moving__lambda_at_lambda_as_field_cpp______ { +pub struct Moving__lambda_at_lambda_as_field_cpp_64_12__ { pub f: FnPtr i32>, pub moves: i32, } -impl Moving__lambda_at_lambda_as_field_cpp______ { +impl Moving__lambda_at_lambda_as_field_cpp_64_12__ { pub unsafe fn new(mut f: FnPtr i32>) -> Self { let mut this = Self { f: f.copy_from(), @@ -78,7 +89,7 @@ impl Moving__lambda_at_lambda_as_field_cpp______ { }; this } - pub unsafe fn move_from(o: *mut Moving__lambda_at_lambda_as_field_cpp______) -> Self { + pub unsafe fn move_from(o: *mut Moving__lambda_at_lambda_as_field_cpp_64_12__) -> Self { let mut this = Self { f: (*o).f.move_from(), moves: (((*o).moves) + (1)), @@ -86,10 +97,10 @@ impl Moving__lambda_at_lambda_as_field_cpp______ { this } } -impl Default for Moving__lambda_at_lambda_as_field_cpp______ { +impl Default for Moving__lambda_at_lambda_as_field_cpp_64_12__ { fn default() -> Self { unsafe { - Moving__lambda_at_lambda_as_field_cpp______ { + Moving__lambda_at_lambda_as_field_cpp_64_12__ { f: FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) * (2)); @@ -129,21 +140,21 @@ pub fn main() { } unsafe fn main_0() -> i32 { { - let mut g: Guard__lambda_at_lambda_as_field_cpp______ = - Guard__lambda_at_lambda_as_field_cpp______ { + let mut g: Guard__lambda_at_lambda_as_field_cpp_34_13__ = + Guard__lambda_at_lambda_as_field_cpp_34_13__ { f: FnPtr::::new(|| unsafe { (*std::cell::LazyCell::force_mut(&mut *&raw mut count_0)).postfix_inc(); }), }; let _dtor_g = ScopedDestructorUnsafe::new( &raw mut g, - Guard__lambda_at_lambda_as_field_cpp______::destructor, + Guard__lambda_at_lambda_as_field_cpp_34_13__::destructor, ); assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut count_0)) == (0))); } assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut count_0)) == (1))); - let mut n: Holder__lambda_at_lambda_as_field_cpp______ = - Holder__lambda_at_lambda_as_field_cpp______ { + let mut n: Holder__lambda_at_lambda_as_field_cpp_39_12__ = + Holder__lambda_at_lambda_as_field_cpp_39_12__ { f: FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) + (1)); @@ -151,12 +162,12 @@ unsafe fn main_0() -> i32 { }), calls: 0, }; - assert!(((unsafe { Holder__lambda_at_lambda_as_field_cpp______::call(&mut n, 2,) }) == (3))); + assert!(((unsafe { Holder__lambda_at_lambda_as_field_cpp_39_12__::call(&mut n, 2,) }) == (3))); assert!(((n.calls) == (1))); let mut cleaned: i32 = 0; { - let mut g: Guard__lambda_at_lambda_as_field_cpp______ = - Guard__lambda_at_lambda_as_field_cpp______ { + let mut g: Guard__lambda_at_lambda_as_field_cpp_45_13__ = + Guard__lambda_at_lambda_as_field_cpp_45_13__ { f: lambda_unsafe!( { let cleaned: *mut i32 = &mut cleaned; @@ -168,14 +179,14 @@ unsafe fn main_0() -> i32 { }; let _dtor_g = ScopedDestructorUnsafe::new( &raw mut g, - Guard__lambda_at_lambda_as_field_cpp______::destructor, + Guard__lambda_at_lambda_as_field_cpp_45_13__::destructor, ); assert!(((cleaned) == (0))); } assert!(((cleaned) == (1))); let mut factor: i32 = 3; - let mut h: Holder__lambda_at_lambda_as_field_cpp______ = - Holder__lambda_at_lambda_as_field_cpp______ { + let mut h: Holder__lambda_at_lambda_as_field_cpp_51_12__ = + Holder__lambda_at_lambda_as_field_cpp_51_12__ { f: lambda_unsafe!( { let factor: i32 = factor; @@ -187,8 +198,8 @@ unsafe fn main_0() -> i32 { calls: 0, }; factor = 100; - assert!(((unsafe { Holder__lambda_at_lambda_as_field_cpp______::call(&mut h, 2,) }) == (6))); - assert!(((unsafe { Holder__lambda_at_lambda_as_field_cpp______::call(&mut h, 5,) }) == (15))); + assert!(((unsafe { Holder__lambda_at_lambda_as_field_cpp_51_12__::call(&mut h, 2,) }) == (6))); + assert!(((unsafe { Holder__lambda_at_lambda_as_field_cpp_51_12__::call(&mut h, 5,) }) == (15))); assert!(((h.calls) == (2))); let mut w: FnPtr i32> = (unsafe { wrap_1(lambda_unsafe!( @@ -204,16 +215,16 @@ unsafe fn main_0() -> i32 { assert!(((unsafe { w.call(2,) }) == (201))); let mut ww: FnPtr i32> = (unsafe { wrap_2(w.copy_from()) }); assert!(((unsafe { ww.call(2,) }) == (202))); - let mut m: Moving__lambda_at_lambda_as_field_cpp______ = - Moving__lambda_at_lambda_as_field_cpp______::new({ + let mut m: Moving__lambda_at_lambda_as_field_cpp_64_12__ = + Moving__lambda_at_lambda_as_field_cpp_64_12__::new({ FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) * (2)); } }) }); - let mut m2: Moving__lambda_at_lambda_as_field_cpp______ = - Moving__lambda_at_lambda_as_field_cpp______::move_from({ &mut m }); + let mut m2: Moving__lambda_at_lambda_as_field_cpp_64_12__ = + Moving__lambda_at_lambda_as_field_cpp_64_12__::move_from({ &mut m }); assert!(((unsafe { m2.f.call(3,) }) == (6))); assert!(((m2.moves) == (1))); return 0; diff --git a/tests/unit/out/unsafe/lambda_decltype_type.rs b/tests/unit/out/unsafe/lambda_decltype_type.rs index 90fe68c77..bd85885c7 100644 --- a/tests/unit/out/unsafe/lambda_decltype_type.rs +++ b/tests/unit/out/unsafe/lambda_decltype_type.rs @@ -8,12 +8,12 @@ use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; #[repr(C)] #[derive(Clone, VaArg, FnPtrArg)] -pub struct Sorted__lambda_at_lambda_decltype_type_cpp______ { +pub struct Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ { pub items: [i32; 4], pub size: i32, pub cmp: FnPtr bool>, } -impl Sorted__lambda_at_lambda_decltype_type_cpp______ { +impl Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ { pub unsafe fn insert(&mut self, mut v: i32) { let mut i: i32 = self.size; 'loop_: while ((i) > (0)) @@ -29,10 +29,10 @@ impl Sorted__lambda_at_lambda_decltype_type_cpp______ { self.size.postfix_inc(); } } -impl Default for Sorted__lambda_at_lambda_decltype_type_cpp______ { +impl Default for Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ { fn default() -> Self { unsafe { - Sorted__lambda_at_lambda_decltype_type_cpp______ { + Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ { items: [0_i32; 4], size: 0, cmp: FnPtr:: bool>::new(|mut a: i32, mut b: i32| -> bool { @@ -44,7 +44,14 @@ impl Default for Sorted__lambda_at_lambda_decltype_type_cpp______ { } } } -impl Sorted__lambda_at_lambda_decltype_type_cpp______ { +#[repr(C)] +#[derive(Clone, VaArg, FnPtrArg)] +pub struct Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ { + pub items: [i32; 4], + pub size: i32, + pub cmp: FnPtr bool>, +} +impl Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ { pub unsafe fn insert(&mut self, mut v: i32) { let mut i: i32 = self.size; 'loop_: while ((i) > (0)) @@ -60,6 +67,21 @@ impl Sorted__lambda_at_lambda_decltype_type_cpp______ { self.size.postfix_inc(); } } +impl Default for Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ { + fn default() -> Self { + unsafe { + Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ { + items: [0_i32; 4], + size: 0, + cmp: FnPtr:: bool>::new(|mut a: i32, mut b: i32| -> bool { + unsafe { + return ((a) < (b)); + } + }), + } + } + } +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -73,19 +95,19 @@ unsafe fn main_0() -> i32 { return ((a) > (b)); } }); - let mut desc: Sorted__lambda_at_lambda_decltype_type_cpp______ = - ::default(); - (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp______::insert(&mut desc, 2) }); - (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp______::insert(&mut desc, 7) }); - (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp______::insert(&mut desc, 4) }); + let mut desc: Sorted__lambda_at_lambda_decltype_type_cpp_22_18__ = + ::default(); + (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp_22_18__::insert(&mut desc, 2) }); + (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp_22_18__::insert(&mut desc, 7) }); + (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp_22_18__::insert(&mut desc, 4) }); assert!(((desc.items[(0) as usize]) == (7))); assert!(((desc.items[(1) as usize]) == (4))); assert!(((desc.items[(2) as usize]) == (2))); - let mut asc: Sorted__lambda_at_lambda_decltype_type_cpp______ = - ::default(); - (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp______::insert(&mut asc, 2) }); - (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp______::insert(&mut asc, 7) }); - (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp______::insert(&mut asc, 4) }); + let mut asc: Sorted__lambda_at_lambda_decltype_type_cpp_19_23__ = + ::default(); + (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp_19_23__::insert(&mut asc, 2) }); + (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp_19_23__::insert(&mut asc, 7) }); + (unsafe { Sorted__lambda_at_lambda_decltype_type_cpp_19_23__::insert(&mut asc, 4) }); assert!(((asc.items[(0) as usize]) == (2))); assert!(((asc.items[(1) as usize]) == (4))); assert!(((asc.items[(2) as usize]) == (7))); diff --git a/tests/unit/out/unsafe/nttp_distinct_specializations.rs b/tests/unit/out/unsafe/nttp_distinct_specializations.rs new file mode 100644 index 000000000..a7dccd609 --- /dev/null +++ b/tests/unit/out/unsafe/nttp_distinct_specializations.rs @@ -0,0 +1,67 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive(Copy, Clone, VaArg, FnPtrArg, Default)] +pub struct S_2_ { + pub v: i32, + pub w: i32, +} +impl S_2_ { + pub unsafe fn get(&self) -> i32 { + return ((self.v) - (self.w)); + } +} +#[repr(C)] +#[derive(Copy, Clone, VaArg, FnPtrArg, Default)] +pub struct S_1_ { + pub v: i32, +} +impl S_1_ { + pub unsafe fn get(&self) -> i32 { + return ((self.v) * (1)); + } +} +#[repr(C)] +#[derive(Copy, Clone, VaArg, FnPtrArg, Default)] +pub struct S_3_ { + pub v: i32, +} +impl S_3_ { + pub unsafe fn get(&self) -> i32 { + return ((self.v) * (3)); + } +} +pub unsafe fn scale_0(mut x: i32) -> i32 { + return ((x) * (1)); +} +pub unsafe fn scale_1(mut x: i32) -> i32 { + return ((x) * (3)); +} +pub unsafe fn scale_2(mut x: i32) -> i32 { + return ((x) - (2)); +} +pub fn main() { + unsafe { + __cpp2rust_init_globals(); + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut s1: S_1_ = S_1_ { v: 5 }; + let mut s2: S_2_ = S_2_ { v: 5, w: 1 }; + let mut s3: S_3_ = S_3_ { v: 5 }; + assert!(((unsafe { S_1_::get(&s1,) }) == (5))); + assert!(((unsafe { S_2_::get(&s2,) }) == (4))); + assert!(((unsafe { S_3_::get(&s3,) }) == (15))); + assert!(((unsafe { scale_0(7,) }) == (7))); + assert!(((unsafe { scale_2(7,) }) == (5))); + assert!(((unsafe { scale_1(7,) }) == (21))); + return 0; +} +pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/pair_get.rs b/tests/unit/out/unsafe/pair_get.rs new file mode 100644 index 000000000..671010f58 --- /dev/null +++ b/tests/unit/out/unsafe/pair_get.rs @@ -0,0 +1,29 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn second_of_0(p: *const (f64, i32)) -> i32 { + return (*&(*p).1); +} +pub unsafe fn first_of_1(p: *const (f64, i32)) -> f64 { + return (*&(*p).0); +} +pub fn main() { + unsafe { + __cpp2rust_init_globals(); + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut p: (f64, i32) = (1.5_f64.into(), 2.into()); + assert!(((*&mut p.0) == (1.5_f64))); + assert!(((*&mut p.1) == (2))); + assert!(((unsafe { first_of_1(&p,) }) == (1.5_f64))); + assert!(((unsafe { second_of_0(&p,) }) == (2))); + return 0; +} +pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/pair_get.cpp b/tests/unit/pair_get.cpp new file mode 100644 index 000000000..0c28cde50 --- /dev/null +++ b/tests/unit/pair_get.cpp @@ -0,0 +1,17 @@ +#include +#include + +static int second_of(const std::pair &p) { return std::get<1>(p); } + +static double first_of(const std::pair &p) { + return std::get<0>(p); +} + +int main() { + std::pair p(1.5, 2); + assert(std::get<0>(p) == 1.5); + assert(std::get<1>(p) == 2); + assert(first_of(p) == 1.5); + assert(second_of(p) == 2); + return 0; +}