Skip to content

Commit 64cc7b5

Browse files
committed
Handle anonymous structs inside records
1 parent 968c177 commit 64cc7b5

4 files changed

Lines changed: 44 additions & 4 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2837,10 +2837,6 @@ std::string Converter::GetRecordName(const clang::NamedDecl *decl) const {
28372837
if (auto it = inner_structs_.find(ID); it != inner_structs_.end()) {
28382838
return it->second;
28392839
}
2840-
if (auto *record = clang::dyn_cast<clang::RecordDecl>(decl);
2841-
record && !record->getIdentifier()) {
2842-
return ID;
2843-
}
28442840
return std::regex_replace(Mapper::ToString(decl), std::regex("::"), "_");
28452841
}
28462842

cpp2rust/converter/converter_lib.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <array>
1212
#include <filesystem>
13+
#include <format>
1314
#include <unordered_set>
1415

1516
#include "converter/lex.h"
@@ -294,6 +295,25 @@ unsigned GetArraySize(clang::QualType array_type) {
294295
return constant_array_ty->getSize().getZExtValue();
295296
}
296297

298+
unsigned GetAnonIndex(const clang::NamedDecl *decl) {
299+
if (auto *parent =
300+
clang::dyn_cast<clang::RecordDecl>(decl->getDeclContext())) {
301+
unsigned counter = 0;
302+
for (auto *d : parent->decls()) {
303+
if (d == decl) {
304+
return counter;
305+
}
306+
auto *named = clang::dyn_cast<clang::NamedDecl>(d);
307+
if (named && named->getKind() == decl->getKind() &&
308+
named->getName().empty()) {
309+
counter++;
310+
}
311+
}
312+
return counter;
313+
}
314+
return 0;
315+
}
316+
297317
std::string GetID(const clang::Decl *decl) {
298318
assert(decl);
299319
const auto file_name = GetFileName(decl);
@@ -315,6 +335,11 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
315335
auto name = decl->getDeclName().isIdentifier() ? decl->getName().str()
316336
: decl->getNameAsString();
317337

338+
if (auto *field = clang::dyn_cast<clang::FieldDecl>(decl);
339+
field && name.empty()) {
340+
return std::format("anon_{}", GetAnonIndex(field));
341+
}
342+
318343
if (auto *fn = clang::dyn_cast<clang::FunctionDecl>(decl)) {
319344
if (!clang::isa<clang::CXXMethodDecl>(fn)) {
320345
auto mangled =

cpp2rust/converter/converter_lib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ std::string GetID(const clang::Decl *decl);
8181

8282
std::string GetNamedDeclAsString(const clang::NamedDecl *decl);
8383

84+
unsigned GetAnonIndex(const clang::NamedDecl *decl);
85+
8486
const char *AccessSpecifierAsString(clang::AccessSpecifier spec);
8587

8688
template <class T> llvm::SmallString<16> GetNumAsString(const T &num) {

cpp2rust/converter/mapper.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <llvm/Support/ThreadPool.h>
99

1010
#include <atomic>
11+
#include <format>
1112
#include <mutex>
1213
#include <regex>
1314
#include <utility>
@@ -713,7 +714,23 @@ std::string ToString(clang::QualType qual_type) {
713714
return normalizeTranslationRule(type);
714715
}
715716

717+
static std::string synthesizeAnonRecordName(const clang::RecordDecl *record) {
718+
std::string parent_name;
719+
if (auto *parent =
720+
clang::dyn_cast<clang::RecordDecl>(record->getDeclContext())) {
721+
parent_name =
722+
parent->getIdentifier() ? parent->getIdentifier()->getName().str();
723+
: synthesizeAnonRecordName(parent);
724+
}
725+
return std::format("{}_anon_{}", parent_name, GetAnonIndex(record));
726+
}
727+
716728
std::string ToString(const clang::NamedDecl *decl) {
729+
if (auto *record = clang::dyn_cast<clang::RecordDecl>(decl);
730+
record && !record->getIdentifier()) {
731+
return synthesizeAnonRecordName(record);
732+
}
733+
717734
std::string out;
718735
llvm::raw_string_ostream os(out);
719736

0 commit comments

Comments
 (0)