diff --git a/main.cpp b/main.cpp index bef8d16a..8f56084b 100644 --- a/main.cpp +++ b/main.cpp @@ -802,6 +802,8 @@ bool IsTypeDefinition(const CXIdxContainerInfo* container) { return false; switch (container->cursor.kind) { + case CXCursor_EnumDecl: + case CXCursor_UnionDecl: case CXCursor_StructDecl: case CXCursor_ClassDecl: return true; @@ -936,6 +938,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { break; } + case CXIdxEntity_EnumConstant: case CXIdxEntity_Field: case CXIdxEntity_Variable: case CXIdxEntity_CXXStaticVariable: @@ -1115,6 +1118,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { break; } + case CXIdxEntity_Enum: + case CXIdxEntity_Union: case CXIdxEntity_Struct: case CXIdxEntity_CXXClass: { @@ -1143,15 +1148,17 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { // Add type-level inheritance information. CXIdxCXXClassDeclInfo const* class_info = clang_index_getCXXClassDeclInfo(decl); - for (unsigned int i = 0; i < class_info->numBases; ++i) { - const CXIdxBaseClassInfo* base_class = class_info->bases[i]; + if (class_info) { + for (unsigned int i = 0; i < class_info->numBases; ++i) { + const CXIdxBaseClassInfo* base_class = class_info->bases[i]; - std::optional parent_type_id = ResolveDeclToType(db, base_class->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer); - TypeDef* type_def = db->Resolve(type_id); // type_def ptr could be invalidated by ResolveDeclToType. - if (parent_type_id) { - TypeDef* parent_type_def = db->Resolve(parent_type_id.value()); - parent_type_def->derived.push_back(type_id); - type_def->parents.push_back(parent_type_id.value()); + std::optional parent_type_id = ResolveDeclToType(db, base_class->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer); + TypeDef* type_def = db->Resolve(type_id); // type_def ptr could be invalidated by ResolveDeclToType. + if (parent_type_id) { + TypeDef* parent_type_def = db->Resolve(parent_type_id.value()); + parent_type_def->derived.push_back(type_id); + type_def->parents.push_back(parent_type_id.value()); + } } } break; @@ -1186,9 +1193,8 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re ParsingDatabase* db = param->db; clang::Cursor cursor(ref->cursor); - // TODO: Index entity call/ctor creation, like Foo().x = 3 - switch (ref->referencedEntity->kind) { + case CXIdxEntity_EnumConstant: case CXIdxEntity_CXXStaticVariable: case CXIdxEntity_Variable: case CXIdxEntity_Field: @@ -1255,6 +1261,8 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re case CXIdxEntity_Typedef: case CXIdxEntity_CXXTypeAlias: + case CXIdxEntity_Enum: + case CXIdxEntity_Union: case CXIdxEntity_Struct: case CXIdxEntity_CXXClass: { @@ -1431,7 +1439,7 @@ int main(int argc, char** argv) { for (std::string path : GetFilesInFolder("tests")) { //if (path != "tests/declaration_vs_definition/class_member_static.cc") continue; - //if (path != "tests/usage/type_usage_typedef_and_using_template.cc") continue; + //if (path != "tests/enums/enum_class_decl.cc") continue; //if (path != "tests/constructors/constructor.cc") continue; //if (path == "tests/constructors/destructor.cc") continue; //if (path == "tests/usage/func_usage_call_method.cc") continue; diff --git a/tests/enums/enum_class_decl.cc b/tests/enums/enum_class_decl.cc new file mode 100644 index 00000000..91e4274e --- /dev/null +++ b/tests/enums/enum_class_decl.cc @@ -0,0 +1,37 @@ +enum class Foo { + A, + B = 20 +}; + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@E@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:1:12", + "vars": [0, 1], + "all_uses": ["1:1:12"] + }], + "functions": [], + "variables": [{ + "id": 0, + "usr": "c:@E@Foo@A", + "short_name": "A", + "qualified_name": "Foo::A", + "definition": "1:2:3", + "declaring_type": 0, + "all_uses": ["1:2:3"] + }, { + "id": 1, + "usr": "c:@E@Foo@B", + "short_name": "B", + "qualified_name": "Foo::B", + "definition": "1:3:3", + "declaring_type": 0, + "all_uses": ["1:3:3"] + }] +} +*/ \ No newline at end of file diff --git a/tests/enums/enum_decl.cc b/tests/enums/enum_decl.cc new file mode 100644 index 00000000..715b0bcc --- /dev/null +++ b/tests/enums/enum_decl.cc @@ -0,0 +1,37 @@ +enum Foo { + A, + B = 20 +}; + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@E@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:1:6", + "vars": [0, 1], + "all_uses": ["1:1:6"] + }], + "functions": [], + "variables": [{ + "id": 0, + "usr": "c:@E@Foo@A", + "short_name": "A", + "qualified_name": "Foo::A", + "definition": "1:2:3", + "declaring_type": 0, + "all_uses": ["1:2:3"] + }, { + "id": 1, + "usr": "c:@E@Foo@B", + "short_name": "B", + "qualified_name": "Foo::B", + "definition": "1:3:3", + "declaring_type": 0, + "all_uses": ["1:3:3"] + }] +} +*/ \ No newline at end of file diff --git a/tests/enums/enum_inherit.cc b/tests/enums/enum_inherit.cc new file mode 100644 index 00000000..794c9c75 --- /dev/null +++ b/tests/enums/enum_inherit.cc @@ -0,0 +1,37 @@ +enum Foo : int { + A, + B = 20 +}; + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@E@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:1:6", + "vars": [0, 1], + "all_uses": ["1:1:6"] + }], + "functions": [], + "variables": [{ + "id": 0, + "usr": "c:@E@Foo@A", + "short_name": "A", + "qualified_name": "Foo::A", + "definition": "1:2:3", + "declaring_type": 0, + "all_uses": ["1:2:3"] + }, { + "id": 1, + "usr": "c:@E@Foo@B", + "short_name": "B", + "qualified_name": "Foo::B", + "definition": "1:3:3", + "declaring_type": 0, + "all_uses": ["1:3:3"] + }] +} +*/ \ No newline at end of file diff --git a/tests/enums/enum_usage.cc b/tests/enums/enum_usage.cc new file mode 100644 index 00000000..b508aeb6 --- /dev/null +++ b/tests/enums/enum_usage.cc @@ -0,0 +1,47 @@ +enum class Foo { + A, + B = 20 +}; + +Foo x = Foo::A; + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@E@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:1:12", + "vars": [0, 1], + "all_uses": ["1:1:12", "*1:6:1", "1:6:9"] + }], + "functions": [], + "variables": [{ + "id": 0, + "usr": "c:@E@Foo@A", + "short_name": "A", + "qualified_name": "Foo::A", + "definition": "1:2:3", + "declaring_type": 0, + "all_uses": ["1:2:3", "1:6:14"] + }, { + "id": 1, + "usr": "c:@E@Foo@B", + "short_name": "B", + "qualified_name": "Foo::B", + "definition": "1:3:3", + "declaring_type": 0, + "all_uses": ["1:3:3"] + }, { + "id": 2, + "usr": "c:@x", + "short_name": "x", + "qualified_name": "x", + "definition": "1:6:5", + "variable_type": 0, + "all_uses": ["1:6:5"] + }] +} +*/ \ No newline at end of file diff --git a/tests/unions/union_decl.cc b/tests/unions/union_decl.cc new file mode 100644 index 00000000..ca9a8771 --- /dev/null +++ b/tests/unions/union_decl.cc @@ -0,0 +1,37 @@ +union Foo { + int a; + bool b; +}; + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@U@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:1:7", + "vars": [0, 1], + "all_uses": ["1:1:7"] + }], + "functions": [], + "variables": [{ + "id": 0, + "usr": "c:@U@Foo@FI@a", + "short_name": "a", + "qualified_name": "Foo::a", + "definition": "1:2:7", + "declaring_type": 0, + "all_uses": ["1:2:7"] + }, { + "id": 1, + "usr": "c:@U@Foo@FI@b", + "short_name": "b", + "qualified_name": "Foo::b", + "definition": "1:3:8", + "declaring_type": 0, + "all_uses": ["1:3:8"] + }] +} +*/ \ No newline at end of file diff --git a/tests/unions/union_usage.cc b/tests/unions/union_usage.cc new file mode 100644 index 00000000..bba5924a --- /dev/null +++ b/tests/unions/union_usage.cc @@ -0,0 +1,58 @@ +union Foo { + int a : 5; + bool b : 3; +}; + +Foo f; + +void act(Foo*) { + f.a = 3; +} + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@U@Foo", + "short_name": "Foo", + "qualified_name": "Foo", + "definition": "1:1:7", + "vars": [0, 1], + "all_uses": ["1:1:7", "*1:6:1", "*1:8:10"] + }], + "functions": [{ + "id": 0, + "usr": "c:@F@act#*$@U@Foo#", + "short_name": "act", + "qualified_name": "act", + "definition": "1:8:6", + "all_uses": ["1:8:6"] + }], + "variables": [{ + "id": 0, + "usr": "c:@U@Foo@FI@a", + "short_name": "a", + "qualified_name": "Foo::a", + "definition": "1:2:7", + "declaring_type": 0, + "all_uses": ["1:2:7", "1:9:5"] + }, { + "id": 1, + "usr": "c:@U@Foo@FI@b", + "short_name": "b", + "qualified_name": "Foo::b", + "definition": "1:3:8", + "declaring_type": 0, + "all_uses": ["1:3:8"] + }, { + "id": 2, + "usr": "c:@f", + "short_name": "f", + "qualified_name": "f", + "definition": "1:6:5", + "variable_type": 0, + "all_uses": ["1:6:5", "1:9:3"] + }] +} +*/ \ No newline at end of file