Skip to content

Commit 1ccc31c

Browse files
committed
Group traits and impls one after another in the generated code
1 parent 0469990 commit 1ccc31c

28 files changed

Lines changed: 221 additions & 212 deletions

‎cpp2rust/converter/converter.cpp‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ std::unordered_set<std::string> Converter::decl_ids_;
2626
std::unordered_set<std::string> Converter::globals_;
2727
std::unordered_set<std::string> Converter::abstract_structs_;
2828
Converter::RecordIndex Converter::record_decls_;
29-
std::map<Converter::DeferredImplHeader, Converter::DeferredImplBody>
30-
Converter::deferred_impls_;
29+
std::map<std::string, Converter::MethodsOnPtr> Converter::methods_on_ptr_;
3130

3231
void Converter::ConvertUniquePtrDeref(clang::CXXOperatorCallExpr *expr) {
3332
bool is_star = expr->getOperator() == clang::OverloadedOperatorKind::OO_Star;
@@ -58,12 +57,16 @@ use std::rc::Rc;
5857
)");
5958
}
6059

61-
std::string Converter::EmitDeferredImpls() {
60+
std::string Converter::EmitMethodsOnPtr() {
6261
std::string out;
63-
for (const auto &[header, body] : deferred_impls_) {
64-
out += header;
62+
for (const auto &[name, methods] : methods_on_ptr_) {
63+
out += methods.trait_header;
6564
out += " {\n";
66-
out += body;
65+
out += methods.trait_body;
66+
out += "}\n";
67+
out += methods.impl_header;
68+
out += " {\n";
69+
out += methods.impl_body;
6770
out += "}\n";
6871
}
6972
return out;

‎cpp2rust/converter/converter.h‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
5454

5555
static std::string EmitOpaqueRecords();
5656

57-
static std::string EmitDeferredImpls();
57+
static std::string EmitMethodsOnPtr();
5858

5959
virtual bool VisitBuiltinType(clang::BuiltinType *type);
6060

@@ -847,9 +847,15 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
847847
std::unordered_map<std::string, bool> entries_;
848848
};
849849
static RecordIndex record_decls_;
850-
using DeferredImplHeader = std::string;
851-
using DeferredImplBody = std::string;
852-
static std::map<DeferredImplHeader, DeferredImplBody> deferred_impls_;
850+
struct MethodsOnPtr {
851+
std::string trait_header;
852+
std::string trait_body;
853+
std::string impl_header;
854+
std::string impl_body;
855+
};
856+
// record name -> trait and impl for Ptr<record>, emitted after all
857+
// translation units.
858+
static std::map<std::string, MethodsOnPtr> methods_on_ptr_;
853859

854860
enum class ExprKind : uint8_t {
855861
Callee,

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,15 +2604,16 @@ ConverterRefCount::TraitName(const clang::CXXRecordDecl *decl) const {
26042604
return GetRecordName(decl) + "Impl";
26052605
}
26062606

2607-
std::string
2608-
ConverterRefCount::TraitHeader(const clang::CXXRecordDecl *decl) const {
2609-
return std::format("pub trait {}", TraitName(decl));
2610-
}
2611-
2612-
std::string
2613-
ConverterRefCount::ImplHeader(const clang::CXXRecordDecl *decl) const {
2614-
return std::format("impl {} for Ptr<{}>", TraitName(decl),
2615-
GetRecordName(decl));
2607+
Converter::MethodsOnPtr &
2608+
ConverterRefCount::MethodsOnPtrFor(const clang::CXXRecordDecl *decl) {
2609+
auto name = GetRecordName(decl);
2610+
auto [it, inserted] = methods_on_ptr_.try_emplace(name);
2611+
if (inserted) {
2612+
it->second.trait_header = std::format("pub trait {}", TraitName(decl));
2613+
it->second.impl_header =
2614+
std::format("impl {} for Ptr<{}>", TraitName(decl), name);
2615+
}
2616+
return it->second;
26162617
}
26172618

26182619
bool ConverterRefCount::ConvertOutOfLineMethod(clang::CXXMethodDecl *decl) {
@@ -2624,7 +2625,7 @@ bool ConverterRefCount::ConvertOutOfLineMethod(clang::CXXMethodDecl *decl) {
26242625
PushMethodTarget push(*this, MethodTarget::PtrImpl);
26252626
ConvertCXXMethodDecl(decl);
26262627
}
2627-
deferred_impls_[ImplHeader(decl->getParent())] += std::move(buf).str();
2628+
MethodsOnPtrFor(decl->getParent()).impl_body += std::move(buf).str();
26282629
return false;
26292630
}
26302631

@@ -2637,7 +2638,7 @@ void ConverterRefCount::ConvertMethodOnPtr(clang::CXXMethodDecl *method) {
26372638
PushMethodTarget push(*this, MethodTarget::TraitDecl);
26382639
ConvertCXXMethodDecl(method);
26392640
}
2640-
deferred_impls_[TraitHeader(record)] += std::move(buf).str();
2641+
MethodsOnPtrFor(record).trait_body += std::move(buf).str();
26412642
}
26422643
if (!method->isThisDeclarationADefinition()) {
26432644
return;
@@ -2647,7 +2648,7 @@ void ConverterRefCount::ConvertMethodOnPtr(clang::CXXMethodDecl *method) {
26472648
PushMethodTarget push(*this, MethodTarget::PtrImpl);
26482649
VisitCXXMethodDecl(method);
26492650
}
2650-
deferred_impls_[ImplHeader(record)] += std::move(buf).str();
2651+
MethodsOnPtrFor(record).impl_body += std::move(buf).str();
26512652
}
26522653

26532654
void ConverterRefCount::ConvertLateInstantiatedMethods(
@@ -2683,9 +2684,9 @@ void ConverterRefCount::ConvertCXXRecordMethods(clang::CXXRecordDecl *decl) {
26832684
}
26842685

26852686
if (!GetUserDefinedDestructor(decl) && HasFieldsNeedingDestruction(decl)) {
2686-
deferred_impls_[TraitHeader(decl)] +=
2687+
MethodsOnPtrFor(decl).trait_body +=
26872688
std::format("fn {}(&self);\n", kDestructorName);
2688-
deferred_impls_[ImplHeader(decl)] += std::format(
2689+
MethodsOnPtrFor(decl).impl_body += std::format(
26892690
"fn {}(&self) {{ {} }}\n", kDestructorName, DestroyMembers(decl));
26902691
}
26912692
}

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,7 @@ class ConverterRefCount final : public Converter {
219219

220220
private:
221221
std::string TraitName(const clang::CXXRecordDecl *decl) const;
222-
std::string TraitHeader(const clang::CXXRecordDecl *decl) const;
223-
std::string ImplHeader(const clang::CXXRecordDecl *decl) const;
222+
MethodsOnPtr &MethodsOnPtrFor(const clang::CXXRecordDecl *decl);
224223
std::string DestroyMembers(const clang::CXXRecordDecl *decl) override;
225224
void EmitScopedDestructor(const clang::VarDecl *decl) override;
226225

‎cpp2rust/cpp2rust_lib.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ std::string TranspileSrc(std::string_view cc_code, Model model,
3131
cc_code, tool_args, std::filesystem::path(filename).filename().string(),
3232
filename.ends_with(".c") ? CLANG_C_COMPILER : CLANG_CXX_COMPILER);
3333
rs_code += Converter::EmitOpaqueRecords();
34-
rs_code += Converter::EmitDeferredImpls();
34+
rs_code += Converter::EmitMethodsOnPtr();
3535
return rs_code;
3636
}
3737

@@ -72,7 +72,7 @@ std::string TranspileDir(std::string_view build_dir, Model model,
7272
FrontendActionFactory factory(rs_code, model, rules_dir);
7373
Tool.run(&factory);
7474
rs_code += Converter::EmitOpaqueRecords();
75-
rs_code += Converter::EmitDeferredImpls();
75+
rs_code += Converter::EmitMethodsOnPtr();
7676
return rs_code;
7777
}
7878
} // namespace cpp2rust

‎tests/multi-file/template_method_late_instantiation/out/refcount/template_method_late_instantiation.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ pub fn f_0(p: Ptr<S_int_>) -> i32 {
4545
let p: Value<Ptr<S_int_>> = Rc::new(RefCell::new(p));
4646
return ({ S_int_Impl::get(&(*p.borrow())) });
4747
}
48+
pub trait S_int_Impl {
49+
fn set(&self, v: i32);
50+
fn get(&self) -> i32;
51+
}
4852
impl S_int_Impl for Ptr<S_int_> {
4953
fn set(&self, v: i32) {
5054
let v: Value<i32> = Rc::new(RefCell::new(v));
@@ -54,7 +58,3 @@ impl S_int_Impl for Ptr<S_int_> {
5458
return (*(*(*self).upgrade().deref()).x.borrow());
5559
}
5660
}
57-
pub trait S_int_Impl {
58-
fn set(&self, v: i32);
59-
fn get(&self) -> i32;
60-
}

‎tests/unit/out/refcount/10_struct.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ fn main_0() -> i32 {
7676
}));
7777
return 0;
7878
}
79+
pub trait GraphImpl {
80+
fn push(&self, src: u32, dst: u32);
81+
}
7982
impl GraphImpl for Ptr<Graph> {
8083
fn push(&self, src: u32, dst: u32) {
8184
let src: Value<u32> = Rc::new(RefCell::new(src));
@@ -106,6 +109,3 @@ impl GraphImpl for Ptr<Graph> {
106109
.write(__rhs);
107110
}
108111
}
109-
pub trait GraphImpl {
110-
fn push(&self, src: u32, dst: u32);
111-
}

‎tests/unit/out/refcount/class.rs‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ fn main_0() -> i32 {
116116
);
117117
return 0;
118118
}
119+
pub trait PairImpl {
120+
fn NOP(&self);
121+
fn GetFirst(&self) -> i32;
122+
fn GetSecond(&self) -> i32;
123+
fn Set(&self, field: Ptr<i32>, new_val: i32) -> i32;
124+
fn SetFirst(&self, new_first: i32) -> i32;
125+
fn SetSecond(&self, new_second: i32) -> i32;
126+
}
119127
impl PairImpl for Ptr<Pair> {
120128
fn NOP(&self) {}
121129
fn GetFirst(&self) -> i32 {
@@ -149,6 +157,9 @@ impl PairImpl for Ptr<Pair> {
149157
}));
150158
}
151159
}
160+
pub trait RouteImpl {
161+
fn SetCost(&self, new_cost: f64) -> f64;
162+
}
152163
impl RouteImpl for Ptr<Route> {
153164
fn SetCost(&self, new_cost: f64) -> f64 {
154165
let new_cost: Value<f64> = Rc::new(RefCell::new(new_cost));
@@ -158,14 +169,3 @@ impl RouteImpl for Ptr<Route> {
158169
return (*old_cost.borrow());
159170
}
160171
}
161-
pub trait PairImpl {
162-
fn NOP(&self);
163-
fn GetFirst(&self) -> i32;
164-
fn GetSecond(&self) -> i32;
165-
fn Set(&self, field: Ptr<i32>, new_val: i32) -> i32;
166-
fn SetFirst(&self, new_first: i32) -> i32;
167-
fn SetSecond(&self, new_second: i32) -> i32;
168-
}
169-
pub trait RouteImpl {
170-
fn SetCost(&self, new_cost: f64) -> f64;
171-
}

‎tests/unit/out/refcount/class_template_lazy_member.rs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,20 +100,20 @@ fn main_0() -> i32 {
100100
assert!(((*({ Box_Point_Impl::get(&p.as_pointer(),) }).x.borrow()) == 4));
101101
return 0;
102102
}
103+
pub trait Box_Point_Impl {
104+
fn get(&self) -> Point;
105+
}
103106
impl Box_Point_Impl for Ptr<Box_Point_> {
104107
fn get(&self) -> Point {
105108
return (*(*(*self).upgrade().deref()).val.borrow()).clone();
106109
}
107110
}
111+
pub trait Box_int_Impl {
112+
fn twice(&self) -> i32;
113+
}
108114
impl Box_int_Impl for Ptr<Box_int_> {
109115
fn twice(&self) -> i32 {
110116
return ((*(*(*self).upgrade().deref()).val.borrow())
111117
+ (*(*(*self).upgrade().deref()).val.borrow()));
112118
}
113119
}
114-
pub trait Box_Point_Impl {
115-
fn get(&self) -> Point;
116-
}
117-
pub trait Box_int_Impl {
118-
fn twice(&self) -> i32;
119-
}

‎tests/unit/out/refcount/class_templates.rs‎

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ fn main_0() -> i32 {
127127
assert!(({ MyContainer_float_Impl::empty(&fmc.as_pointer(),) }));
128128
return 0;
129129
}
130+
pub trait MyContainer_char_Impl {
131+
fn empty(&self) -> bool;
132+
fn size(&self) -> usize;
133+
fn back(&self) -> Ptr<u8>;
134+
fn pop_back(&self);
135+
fn push_back(&self, item: Ptr<u8>);
136+
}
130137
impl MyContainer_char_Impl for Ptr<MyContainer_char_> {
131138
fn empty(&self) -> bool {
132139
return (*(*(*self).upgrade().deref()).vec_.borrow()).is_empty();
@@ -148,6 +155,13 @@ impl MyContainer_char_Impl for Ptr<MyContainer_char_> {
148155
};
149156
}
150157
}
158+
pub trait MyContainer_float_Impl {
159+
fn empty(&self) -> bool;
160+
fn size(&self) -> usize;
161+
fn back(&self) -> Ptr<f32>;
162+
fn pop_back(&self);
163+
fn push_back(&self, item: Ptr<f32>);
164+
}
151165
impl MyContainer_float_Impl for Ptr<MyContainer_float_> {
152166
fn empty(&self) -> bool {
153167
return (*(*(*self).upgrade().deref()).vec_.borrow()).is_empty();
@@ -169,6 +183,13 @@ impl MyContainer_float_Impl for Ptr<MyContainer_float_> {
169183
};
170184
}
171185
}
186+
pub trait MyContainer_int_Impl {
187+
fn empty(&self) -> bool;
188+
fn size(&self) -> usize;
189+
fn back(&self) -> Ptr<i32>;
190+
fn pop_back(&self);
191+
fn push_back(&self, item: Ptr<i32>);
192+
}
172193
impl MyContainer_int_Impl for Ptr<MyContainer_int_> {
173194
fn empty(&self) -> bool {
174195
return (*(*(*self).upgrade().deref()).vec_.borrow()).is_empty();
@@ -190,24 +211,3 @@ impl MyContainer_int_Impl for Ptr<MyContainer_int_> {
190211
};
191212
}
192213
}
193-
pub trait MyContainer_char_Impl {
194-
fn empty(&self) -> bool;
195-
fn size(&self) -> usize;
196-
fn back(&self) -> Ptr<u8>;
197-
fn pop_back(&self);
198-
fn push_back(&self, item: Ptr<u8>);
199-
}
200-
pub trait MyContainer_float_Impl {
201-
fn empty(&self) -> bool;
202-
fn size(&self) -> usize;
203-
fn back(&self) -> Ptr<f32>;
204-
fn pop_back(&self);
205-
fn push_back(&self, item: Ptr<f32>);
206-
}
207-
pub trait MyContainer_int_Impl {
208-
fn empty(&self) -> bool;
209-
fn size(&self) -> usize;
210-
fn back(&self) -> Ptr<i32>;
211-
fn pop_back(&self);
212-
fn push_back(&self, item: Ptr<i32>);
213-
}

0 commit comments

Comments
 (0)