add method inheritance support

This commit is contained in:
Jacob Dufault 2017-02-19 23:06:38 -08:00
parent da6fbf7c5a
commit 657260eeab
5 changed files with 177 additions and 2 deletions

View File

@ -1354,10 +1354,12 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
func_def->all_uses.push_back(decl->loc);
bool is_pure_virtual = clang_CXXMethod_isPureVirtual(decl->cursor);
// Add function usage information. We only want to do it once per
// definition/declaration. Do it on definition since there should only ever
// be one of those in the entire program.
if (decl->isDefinition && IsTypeDefinition(decl->semanticContainer)) {
if ((decl->isDefinition || is_pure_virtual) && IsTypeDefinition(decl->semanticContainer)) {
TypeId declaring_type_id = db->ToTypeId(decl->semanticContainer->cursor);
TypeDef* declaring_type_def = db->Resolve(declaring_type_id);
func_def->declaring_type = declaring_type_id;
@ -1370,7 +1372,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
if (decl->isDefinition) {
if (decl->isDefinition || is_pure_virtual) {
// Mark type usage for parameters as interesting. We handle this here
// instead of inside var declaration because clang will not emit a var
// declaration for an unnamed parameter, but we still want to mark the
@ -1387,6 +1389,29 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
break;
}
}
// Process inheritance.
//void clang_getOverriddenCursors(CXCursor cursor, CXCursor **overridden, unsigned *num_overridden);
//void clang_disposeOverriddenCursors(CXCursor *overridden);
if (clang_CXXMethod_isVirtual(decl->cursor)) {
CXCursor* overridden;
unsigned int num_overridden;
clang_getOverriddenCursors(decl->cursor, &overridden, &num_overridden);
// TODO: How to handle multiple parent overrides??
for (unsigned int i = 0; i < num_overridden; ++i) {
clang::Cursor parent = overridden[i];
FuncId parent_id = db->ToFuncId(parent.get_usr());
FuncDef* parent_def = db->Resolve(parent_id);
func_def = db->Resolve(func_id); // ToFuncId invalidated func_def
func_def->base = parent_id;
parent_def->derived.push_back(func_id);
}
clang_disposeOverriddenCursors(overridden);
}
}
/*

View File

@ -0,0 +1,27 @@
class Parent {};
class Derived : public Parent {};
/*
OUTPUT:
{
"types": [{
"id": 0,
"usr": "c:@S@Parent",
"short_name": "Parent",
"qualified_name": "Parent",
"definition": "tests/inheritance/class_inherit.cc:1:7",
"derived": [1],
"all_uses": ["tests/inheritance/class_inherit.cc:1:7", "tests/inheritance/class_inherit.cc:2:24"]
}, {
"id": 1,
"usr": "c:@S@Derived",
"short_name": "Derived",
"qualified_name": "Derived",
"definition": "tests/inheritance/class_inherit.cc:2:7",
"parents": [0],
"all_uses": ["tests/inheritance/class_inherit.cc:2:7"]
}],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,47 @@
class Root {};
class MiddleA : public Root {};
class MiddleB : public Root {};
class Derived : public MiddleA, public MiddleB {};
/*
OUTPUT:
{
"types": [{
"id": 0,
"usr": "c:@S@Root",
"short_name": "Root",
"qualified_name": "Root",
"definition": "tests/inheritance/class_multiple_inherit.cc:1:7",
"derived": [1, 2],
"all_uses": ["tests/inheritance/class_multiple_inherit.cc:1:7", "tests/inheritance/class_multiple_inherit.cc:2:24", "tests/inheritance/class_multiple_inherit.cc:3:24"]
}, {
"id": 1,
"usr": "c:@S@MiddleA",
"short_name": "MiddleA",
"qualified_name": "MiddleA",
"definition": "tests/inheritance/class_multiple_inherit.cc:2:7",
"parents": [0],
"derived": [3],
"all_uses": ["tests/inheritance/class_multiple_inherit.cc:2:7", "tests/inheritance/class_multiple_inherit.cc:4:24"]
}, {
"id": 2,
"usr": "c:@S@MiddleB",
"short_name": "MiddleB",
"qualified_name": "MiddleB",
"definition": "tests/inheritance/class_multiple_inherit.cc:3:7",
"parents": [0],
"derived": [3],
"all_uses": ["tests/inheritance/class_multiple_inherit.cc:3:7", "tests/inheritance/class_multiple_inherit.cc:4:40"]
}, {
"id": 3,
"usr": "c:@S@Derived",
"short_name": "Derived",
"qualified_name": "Derived",
"definition": "tests/inheritance/class_multiple_inherit.cc:4:7",
"parents": [1, 2],
"all_uses": ["tests/inheritance/class_multiple_inherit.cc:4:7"]
}],
"functions": [],
"variables": []
}
*/

View File

@ -0,0 +1,48 @@
class Root {
virtual void foo();
};
class Derived : public Root {
void foo() override {}
};
/*
OUTPUT:
{
"types": [{
"id": 0,
"usr": "c:@S@Root",
"short_name": "Root",
"qualified_name": "Root",
"definition": "tests/inheritance/function_override.cc:1:7",
"derived": [1],
"all_uses": ["tests/inheritance/function_override.cc:1:7", "tests/inheritance/function_override.cc:4:24"]
}, {
"id": 1,
"usr": "c:@S@Derived",
"short_name": "Derived",
"qualified_name": "Derived",
"definition": "tests/inheritance/function_override.cc:4:7",
"parents": [0],
"funcs": [1],
"all_uses": ["tests/inheritance/function_override.cc:4:7"]
}],
"functions": [{
"id": 0,
"usr": "c:@S@Root@F@foo#",
"short_name": "foo",
"qualified_name": "Root::foo",
"derived": [1],
"all_uses": ["tests/inheritance/function_override.cc:2:16"]
}, {
"id": 1,
"usr": "c:@S@Derived@F@foo#",
"short_name": "foo",
"qualified_name": "Derived::foo",
"definition": "tests/inheritance/function_override.cc:5:8",
"declaring_type": 1,
"base": 0,
"all_uses": ["tests/inheritance/function_override.cc:5:8"]
}],
"variables": []
}
*/

View File

@ -0,0 +1,28 @@
class IFoo {
virtual void foo() = 0 {}
};
/*
OUTPUT:
{
"types": [{
"id": 0,
"usr": "c:@S@IFoo",
"short_name": "IFoo",
"qualified_name": "IFoo",
"definition": "tests/inheritance/interface_pure_virtual.cc:1:7",
"funcs": [0],
"all_uses": ["tests/inheritance/interface_pure_virtual.cc:1:7"]
}],
"functions": [{
"id": 0,
"usr": "c:@S@IFoo@F@foo#",
"short_name": "foo",
"qualified_name": "IFoo::foo",
"definition": "tests/inheritance/interface_pure_virtual.cc:2:16",
"declaring_type": 0,
"all_uses": ["tests/inheritance/interface_pure_virtual.cc:2:16"]
}],
"variables": []
}
*/