diff --git a/src/context.c b/src/context.c index 7b8c41e..dcee371 100644 --- a/src/context.c +++ b/src/context.c @@ -402,6 +402,18 @@ void resect_visit_cursor_for_declaration(resect_visit_context context, CXCursor return; } + // Enables walking `using' declarations to look for inherited constructors + if (cursor_kind == CXCursor_UsingDeclaration) { + CXCursor definition = clang_getCursorDefinition(cursor); + int overload_count = clang_getNumOverloadedDecls(definition); + for (int i = 0; i < overload_count; ++i) { + CXCursor overload = clang_getOverloadedDecl(definition, i); + if (clang_getCursorKind(overload) == CXCursor_Constructor) { + resect_visit_cursor_for_declaration(context, overload, data); + } + } + } + if (resect_is_forward_declaration(cursor)) { CXCursor definition = clang_getCursorDefinition(cursor); if ((clang_getCursorKind(definition) < CXCursor_FirstInvalid diff --git a/src/decl.c b/src/decl.c index 6e0976e..34dcd57 100644 --- a/src/decl.c +++ b/src/decl.c @@ -766,6 +766,7 @@ typedef struct P_resect_record_data { resect_collection methods; resect_collection parents; resect_bool abstract; + resect_bool has_inherited_constructor; } *resect_record_data; resect_bool resect_is_struct(resect_decl decl) { @@ -791,6 +792,12 @@ resect_bool resect_record_is_abstract(resect_decl decl) { return data->abstract; } +resect_bool resect_record_has_inherited_constructor(resect_decl decl) { + assert(resect_is_struct(decl)); + resect_record_data data = decl->data; + return data->has_inherited_constructor; +} + resect_collection resect_record_parents(resect_decl decl) { assert(resect_is_struct(decl)); resect_record_data data = decl->data; @@ -835,6 +842,8 @@ void resect_field_init(resect_visit_context visit_context, resect_translation_co decl->data = data; } +void resect_create_record_child(resect_decl_child_visit_data visit_data, CXCursor cursor); + enum CXChildVisitResult resect_visit_record_child(CXCursor cursor, CXCursor parent, CXClientData data) { resect_decl_child_visit_data visit_data = data; @@ -851,6 +860,28 @@ enum CXChildVisitResult resect_visit_record_child(CXCursor cursor, CXCursor pare return CXChildVisit_Continue; } + if (clang_getCursorKind(cursor) == CXCursor_UsingDeclaration) { + CXCursor definition = clang_getCursorDefinition(cursor); + // There's always more than one constructor; the copy and move constructors + // exist even if they're marked `= delete'. + int overload_count = clang_getNumOverloadedDecls(definition); + for (int i = 0; i < overload_count; ++i) { + CXCursor overload = clang_getOverloadedDecl(definition, i); + if (clang_getCursorKind(overload) == CXCursor_Constructor) { + record_data->has_inherited_constructor = resect_true; + resect_create_record_child(visit_data, overload); + } + } + } else { + resect_create_record_child(visit_data, cursor); + } + + return CXChildVisit_Continue; +} + +void resect_create_record_child(resect_decl_child_visit_data visit_data, CXCursor cursor) { + resect_record_data record_data = visit_data->parent->data; + resect_decl_result decl_result = resect_decl_create(visit_data->visit_context, visit_data->translation_context, cursor); @@ -869,8 +900,6 @@ enum CXChildVisitResult resect_visit_record_child(CXCursor cursor, CXCursor pare default:; } } - - return CXChildVisit_Continue; } void resect_record_data_free(void *data, resect_set deallocated) { @@ -893,6 +922,7 @@ void resect_record_init(resect_visit_context visit_context, resect_translation_c data->fields = resect_collection_create(); data->parents = resect_collection_create(); data->abstract = convert_bool_from_uint(clang_CXXRecord_isAbstract(cursor)); + data->has_inherited_constructor = resect_false; decl->data_deallocator = resect_record_data_free; decl->data = data;