@@ -78,8 +78,41 @@ namespace codetree{
7878 // Replace all '::' occurences by '!':
7979 return std::regex_replace (cpp_name, std::regex (" ::" ), " !" );
8080 }
81+
82+ bool isAssignable (CXCursor type_def){
83+ if (verbose > 3 ) std::cerr << __FUNCTION__ << " (" << type_def << " )\n " ;
84+
85+ struct data_t {
86+ bool copy_assignment_deleted;
87+ bool copy_assignment_defined;
88+ bool move_assignment_deleted;
89+ } data = {false , false , false };
90+
91+ clang_visitChildren (type_def, [](CXCursor cursor, CXCursor, CXClientData data_){
92+ auto & data = *static_cast <data_t *>(data_);
93+ const auto & access = clang_getCXXAccessSpecifier (cursor);
94+ if (clang_CXXMethod_isCopyAssignmentOperator (cursor)){
95+ if (clang_CXXMethod_isDeleted (cursor) || access != CX_CXXPublic){
96+ data.copy_assignment_deleted = true ;
97+ } else {
98+ data.copy_assignment_defined = true ;
99+ }
100+ }
101+
102+ if (clang_CXXMethod_isMoveAssignmentOperator (cursor)
103+ && (clang_CXXMethod_isDeleted (cursor) || access != CX_CXXPublic)){
104+ data.move_assignment_deleted = true ;
105+ }
106+ return CXChildVisit_Continue;
107+ }, &data);
108+
109+ bool not_assignable = data.copy_assignment_deleted
110+ || (data.move_assignment_deleted && !data.copy_assignment_defined ) ;
111+ return !not_assignable;
112+ }
81113}
82114
115+
83116CXCursor
84117CodeTree::getParentClassForWrapper (CXCursor cursor) const {
85118 if (verbose > 5 ) std::cerr << " Calling getParentClassForWrapper("
@@ -474,11 +507,13 @@ CodeTree::generate_cxx_for_type(std::ostream& o,
474507 if (accessor_gen != accessor_mode_t ::none){
475508 // skip field with anomymous struct types:
476509 bool anonymous = false ;
510+ bool assignable = true ;
477511 CXType field_type = clang_getCursorType (f);
478512 if (field_type.kind != CXType_Invalid){
479513 auto def = clang_getTypeDeclaration (field_type);
480- if (!clang_Cursor_isNull (def) && clang_Cursor_isAnonymous (def)){
481- anonymous = true ;
514+ if (!clang_Cursor_isNull (def)){
515+ anonymous = clang_Cursor_isAnonymous (def);
516+ assignable = isAssignable (def);
482517 }
483518 }
484519 if (anonymous){
@@ -487,7 +522,8 @@ CodeTree::generate_cxx_for_type(std::ostream& o,
487522 << " because its type is anonymous.\n " ;
488523 }
489524 } else {
490- generate_accessor_cxx (o, &t, f, accessor_gen == accessor_mode_t ::getter, 2 );
525+ bool getter_only = (accessor_gen == accessor_mode_t ::getter || !assignable);
526+ generate_accessor_cxx (o, &t, f, getter_only, 2 );
491527 }
492528 }
493529 }
@@ -925,9 +961,10 @@ void CodeTree::set_type_rcd_ctor_info(TypeRcd& rcd){
925961 bool explicit_def_ctor;
926962 bool implicit_def_ctor;
927963 bool public_dtor;
964+ int assignable;
928965 int n_def_ctor_decls;
929966 const CodeTree* tree;
930- } data = {false , true , true , 0 , this };
967+ } data = {false , true , true , true , 0 , this };
931968
932969 clang_visitChildren (rcd.cursor , [](CXCursor cursor, CXCursor, CXClientData data_){
933970 auto & data = *static_cast <data_t *>(data_);
@@ -950,9 +987,10 @@ void CodeTree::set_type_rcd_ctor_info(TypeRcd& rcd){
950987 data.public_dtor = false ;
951988 }
952989 }
990+
953991 return CXChildVisit_Continue;
954992 }, &data);
955-
993+
956994 bool finalize_vetoed = false ;
957995 auto it = find (finalizers_to_veto_.begin (), finalizers_to_veto_.end (), rcd.type_name );
958996 if (it != finalizers_to_veto_.end ()){
@@ -3174,3 +3212,5 @@ void CodeTree::set_mapped_types(const std::vector<std::string>& name_map){
31743212 }
31753213 }
31763214}
3215+
3216+
0 commit comments