@@ -75,6 +75,7 @@ static const char rust_keywords[][12] = {
7575 " safe" ,
7676 // Standard library keywords
7777 " vec" ,
78+ " Err" ,
7879};
7980
8081namespace cpp2rust {
@@ -301,6 +302,13 @@ bool IsUserDefinedDecl(const clang::Decl *decl) {
301302 !src_mgr.isInSystemMacro (src_loc);
302303}
303304
305+ bool IsAbstractUserClass (const clang::RecordDecl *decl) {
306+ auto cxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
307+ auto definition = cxx ? cxx->getDefinition () : nullptr ;
308+ return definition && IsUserDefinedDecl (definition) &&
309+ definition->isAbstract ();
310+ }
311+
304312bool RefersToUserDefinedDecl (const clang::Expr *expr) {
305313 expr = expr->IgnoreParenImpCasts ();
306314 const clang::Decl *decl = nullptr ;
@@ -912,6 +920,23 @@ static size_t GetDeclId(const clang::NamedDecl *decl, bool internal) {
912920 return type_mapping.try_emplace (key, type_mapping.size ()).first ->second ;
913921}
914922
923+ void EscapeRustKeyword (std::string &name) {
924+ if (!name.empty () &&
925+ std::ranges::all_of (name, [](char c) { return c == ' _' ; })) {
926+ name += ' _' ;
927+ }
928+ for (auto &keyword : rust_keywords) {
929+ if (!name.starts_with (keyword))
930+ continue ;
931+
932+ auto suffix = std::string_view (name).substr (strlen (keyword));
933+ if (std::ranges::all_of (suffix, [](char c) { return c == ' _' ; })) {
934+ name += ' _' ;
935+ break ;
936+ }
937+ }
938+ }
939+
915940std::string GetNamedDeclAsString (const clang::NamedDecl *decl) {
916941 auto name = decl->getDeclName ().isIdentifier () ? decl->getName ().str ()
917942 : decl->getNameAsString ();
@@ -927,13 +952,24 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
927952 }
928953 }
929954
955+ auto *anonymous_record_var = clang::dyn_cast<clang::VarDecl>(decl);
956+ if (anonymous_record_var) {
957+ auto *record = anonymous_record_var->getType ()->getAsRecordDecl ();
958+ if (clang::isa<clang::ParmVarDecl>(decl) || !record ||
959+ record->getIdentifier ()) {
960+ anonymous_record_var = nullptr ;
961+ }
962+ }
963+
930964 // Anonymous record or enum
931- if (name.empty () && (clang::isa<clang::RecordDecl>(decl) ||
932- clang::isa<clang::FieldDecl>(decl) ||
933- clang::isa<clang::EnumDecl>(decl))) {
965+ if (name.empty () &&
966+ (clang::isa<clang::RecordDecl>(decl) ||
967+ clang::isa<clang::FieldDecl>(decl) || anonymous_record_var ||
968+ clang::isa<clang::EnumDecl>(decl))) {
934969 const clang::NamedDecl *target = decl;
935- if (auto *field = clang::dyn_cast<clang::FieldDecl>(decl)) {
936- if (auto *record = field->getType ()->getAsRecordDecl ();
970+ if (clang::isa<clang::FieldDecl, clang::VarDecl>(decl)) {
971+ auto type = clang::cast<clang::ValueDecl>(decl)->getType ();
972+ if (auto *record = type->getAsRecordDecl ();
937973 record && !record->getIdentifier ()) {
938974 target = record;
939975 }
@@ -962,24 +998,7 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
962998 name += std::to_string (*id);
963999 }
9641000
965- // transform decl names that are rust keywords:
966- // keyword -> keyword_
967- // keyword_ -> keyword__
968- // etc
969- if (!name.empty () &&
970- std::ranges::all_of (name, [](char c) { return c == ' _' ; })) {
971- name += ' _' ;
972- }
973- for (auto &keyword : rust_keywords) {
974- if (!name.starts_with (keyword))
975- continue ;
976-
977- auto suffix = std::string_view (name).substr (strlen (keyword));
978- if (std::ranges::all_of (suffix, [](char c) { return c == ' _' ; })) {
979- name += ' _' ;
980- break ;
981- }
982- }
1001+ EscapeRustKeyword (name);
9831002
9841003 if (name.empty ()) {
9851004 auto *pdecl = llvm::dyn_cast<clang::ParmVarDecl>(decl);
0 commit comments