Skip to content

Commit 739c990

Browse files
committed
Use derives to determine if record is copyable
1 parent 628650a commit 739c990

4 files changed

Lines changed: 27 additions & 2 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,12 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) {
664664
}
665665

666666
bool Converter::RecordDerivesCopy(const clang::RecordDecl *decl) {
667+
auto *derives = Mapper::MappedDerives(ctx_.getCanonicalTagType(decl));
668+
return derives &&
669+
std::find(derives->begin(), derives->end(), "Copy") != derives->end();
670+
}
671+
672+
bool Converter::RecordFieldsCopyable(const clang::RecordDecl *decl) {
667673
for (auto f : decl->fields()) {
668674
// Records that contain std::vector, std::array, std::string or anything
669675
// that is translated to Vec<>, do not derive Copy
@@ -750,8 +756,11 @@ void Converter::EmitRustStructOrUnion(clang::RecordDecl *decl) {
750756
if (EmitsReprCForRecords()) {
751757
StrCat("#[repr(C)]");
752758
}
759+
auto attrs = GetStructAttributes(decl);
760+
Mapper::SetDerives(ctx_.getCanonicalTagType(decl),
761+
std::vector<std::string>(attrs.begin(), attrs.end()));
753762
StrCat("#[derive(");
754-
for (auto *attr : GetStructAttributes(decl)) {
763+
for (auto *attr : attrs) {
755764
StrCat(attr, ',');
756765
}
757766
StrCat(")]");
@@ -3101,6 +3110,8 @@ bool Converter::VisitEnumDecl(clang::EnumDecl *decl) {
31013110
return false;
31023111
}
31033112
Mapper::AddRuleForUserDefinedType(decl);
3113+
Mapper::SetDerives(ctx_.getCanonicalTagType(decl),
3114+
{"Clone", "Copy", "PartialEq", "Debug", "Default"});
31043115
StrCat("#[derive(Clone, Copy, PartialEq, Debug, Default)]");
31053116
StrCat(std::format("enum {}", GetRecordName(decl)));
31063117
StrCat('{');
@@ -3480,7 +3491,7 @@ Converter::GetStructAttributes(const clang::RecordDecl *decl) {
34803491

34813492
std::vector<const char *> struct_attrs;
34823493

3483-
if (RecordDerivesCopy(decl)) {
3494+
if (RecordFieldsCopyable(decl)) {
34843495
struct_attrs.emplace_back("Copy");
34853496
}
34863497

cpp2rust/converter/converter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
587587

588588
bool RecordDerivesCopy(const clang::RecordDecl *decl);
589589

590+
bool RecordFieldsCopyable(const clang::RecordDecl *decl);
591+
590592
bool ShouldReplaceWithMappedBody(clang::DeclRefExpr *expr) const;
591593

592594
std::string *rs_code_;

cpp2rust/converter/mapper.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,16 @@ bool MapsToRefcountPointer(clang::QualType qual_type) {
702702
return rule && rule->type_info.is_refcount_pointer;
703703
}
704704

705+
const std::vector<std::string> *MappedDerives(clang::QualType qual_type) {
706+
auto rule = search(qual_type).first;
707+
return rule ? &rule->type_info.derives : nullptr;
708+
}
709+
710+
void SetDerives(clang::QualType qual_type, std::vector<std::string> derives) {
711+
if (auto *rule = search(qual_type).first) {
712+
rule->type_info.derives = std::move(derives);
713+
}
714+
}
705715
bool ReturnsPointer(const clang::Expr *expr) {
706716
auto rule = search(expr);
707717
return rule && rule->return_type.is_pointer();

cpp2rust/converter/mapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ std::string GetParamType(const clang::Expr *expr, unsigned index);
3737
bool ParamIsPointer(const clang::Expr *expr, unsigned index);
3838
bool MapsToPointer(clang::QualType qual_type);
3939
bool MapsToRefcountPointer(clang::QualType qual_type);
40+
const std::vector<std::string> *MappedDerives(clang::QualType qual_type);
41+
void SetDerives(clang::QualType qual_type, std::vector<std::string> derives);
4042

4143
enum class ScalarSugar {
4244
kDesugar,

0 commit comments

Comments
 (0)