better param index, using index

This commit is contained in:
Jacob Dufault 2017-02-19 18:35:56 -08:00
parent 7701822aa9
commit 3cd39ae91a
2 changed files with 72 additions and 28 deletions

View File

@ -129,9 +129,6 @@ struct FuncDef {
// All usages. For interesting usages, see callees. // All usages. For interesting usages, see callees.
std::vector<clang::SourceLocation> all_uses; std::vector<clang::SourceLocation> all_uses;
// Indexer internal state. Do not expose.
bool needs_return_type_index = false;
FuncDef(FuncId id, const std::string& usr) : id(id), usr(usr) { FuncDef(FuncId id, const std::string& usr) : id(id), usr(usr) {
assert(usr.size() > 0); assert(usr.size() > 0);
} }
@ -1275,16 +1272,31 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
declaring_type_def->funcs.push_back(func_id); declaring_type_def->funcs.push_back(func_id);
} }
// Always recompute this, as we will visit the parameter references next
// (before visiting another declaration). If we only want to mark the
// return type on the definition interesting, we could only compute this
// if we're parsing the definition declaration.
//func_def->needs_return_type_index = !clang::Cursor(decl->cursor).get_type().get_return_type().is_fundamental();
std::string return_type_usr = clang::Cursor(decl->cursor).get_type().get_return_type().strip_qualifiers().get_usr(); std::string return_type_usr = clang::Cursor(decl->cursor).get_type().get_return_type().strip_qualifiers().get_usr();
if (return_type_usr != "") if (return_type_usr != "")
InsertInterestingTypeReference(db, db->ToTypeId(return_type_usr), decl->cursor); InsertInterestingTypeReference(db, db->ToTypeId(return_type_usr), decl->cursor);
if (decl->isDefinition) {
// Search for unnamed parameter and and mark them as interesting type
// usages. The clang indexer will not mark them as declarations.
// TODO: Do a similar thing for function decl parameter usages.
clang::Cursor cursor = decl->cursor;
for (clang::Cursor arg : cursor.get_arguments()) {
switch (arg.get_kind()) {
case CXCursor_ParmDecl:
if (arg.get_spelling() == "") {
std::string param_type_usr = arg.get_type().strip_qualifiers().get_usr();
if (param_type_usr != "") {
InsertInterestingTypeReference(db, db->ToTypeId(param_type_usr), arg);
}
}
break;
}
}
}
/* /*
std::optional<FuncId> base; std::optional<FuncId> base;
std::vector<FuncId> derived; std::vector<FuncId> derived;
@ -1296,6 +1308,30 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
break; break;
} }
case CXIdxEntity_Typedef:
case CXIdxEntity_CXXTypeAlias:
{
TypeId type_id = db->ToTypeId(decl->entityInfo->USR);
std::optional<clang::Cursor> type_ref = FindChildOfKind(decl->cursor, CXCursor_TypeRef);
assert(type_ref.has_value());
TypeId alias_of = db->ToTypeId(type_ref.value().get_referenced().get_usr());
TypeDef* type_def = db->Resolve(type_id);
type_def->alias_of = alias_of;
db->Resolve(alias_of)->interesting_uses.push_back(type_ref.value().get_source_location());
type_def->short_name = decl->entityInfo->name;
type_def->qualified_name = ns->QualifiedName(decl->semanticContainer, type_def->short_name);
type_def->definition = decl->loc;
type_def->all_uses.push_back(decl->loc);
break;
}
case CXIdxEntity_Struct: case CXIdxEntity_Struct:
case CXIdxEntity_CXXClass: case CXIdxEntity_CXXClass:
{ {
@ -1338,6 +1374,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
default: default:
std::cout << "!! Unhandled indexDeclaration: " << clang::Cursor(decl->cursor).ToString() << " at " << clang::SourceLocation(decl->loc).ToString() << std::endl; std::cout << "!! Unhandled indexDeclaration: " << clang::Cursor(decl->cursor).ToString() << " at " << clang::SourceLocation(decl->loc).ToString() << std::endl;
std::cout << " entityInfo->kind = " << decl->entityInfo->kind << std::endl;
std::cout << " entityInfo->USR = " << decl->entityInfo->USR << std::endl; std::cout << " entityInfo->USR = " << decl->entityInfo->USR << std::endl;
if (decl->declAsContainer) if (decl->declAsContainer)
std::cout << " declAsContainer = " << clang::Cursor(decl->declAsContainer->cursor).ToString() << std::endl; std::cout << " declAsContainer = " << clang::Cursor(decl->declAsContainer->cursor).ToString() << std::endl;
@ -1409,6 +1446,8 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
break; break;
} }
case CXIdxEntity_Typedef:
case CXIdxEntity_CXXTypeAlias:
case CXIdxEntity_Struct: case CXIdxEntity_Struct:
case CXIdxEntity_CXXClass: case CXIdxEntity_CXXClass:
{ {
@ -1657,7 +1696,7 @@ int main(int argc, char** argv) {
// TODO: Fix all existing tests. // TODO: Fix all existing tests.
//if (path == "tests/usage/type_usage_declare_extern.cc") continue; //if (path == "tests/usage/type_usage_declare_extern.cc") continue;
if (path == "tests/constructors/constructor.cc") continue; if (path == "tests/constructors/constructor.cc") continue;
if (path != "tests/usage/type_usage_on_return_type.cc") continue; if (path != "tests/usage/type_usage_typedef_and_using.cc") continue;
//if (path != "tests/usage/type_usage_declare_local.cc") continue; //if (path != "tests/usage/type_usage_declare_local.cc") continue;
//if (path != "tests/usage/func_usage_addr_method.cc") continue; //if (path != "tests/usage/func_usage_addr_method.cc") continue;
//if (path != "tests/usage/func_usage_template_func.cc") continue; //if (path != "tests/usage/func_usage_template_func.cc") continue;

View File

@ -1,12 +1,12 @@
struct Foo; struct Foo;
using Foo1 = Foo; using Foo1 = Foo*;
typedef Foo Foo2; typedef Foo Foo2;
using Foo3 = Foo1; using Foo3 = Foo1;
void accept(Foo*); void accept(Foo*) {}
void accept1(Foo1*); void accept1(Foo1*) {}
void accept2(Foo2*); void accept2(Foo2*) {}
void accept3(Foo3*); void accept3(Foo3*) {}
/* /*
OUTPUT: OUTPUT:
@ -14,10 +14,8 @@ OUTPUT:
"types": [{ "types": [{
"id": 0, "id": 0,
"usr": "c:@S@Foo", "usr": "c:@S@Foo",
"short_name": "Foo", "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:1:8", "tests/usage/type_usage_typedef_and_using.cc:2:14", "tests/usage/type_usage_typedef_and_using.cc:3:9", "tests/usage/type_usage_typedef_and_using.cc:6:13"],
"qualified_name": "Foo", "interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:2:14", "tests/usage/type_usage_typedef_and_using.cc:3:9", "tests/usage/type_usage_typedef_and_using.cc:6:13"]
"declaration": "tests/usage/type_usage_typedef_and_using.cc:1:8",
"uses": ["tests/usage/type_usage_typedef_and_using.cc:6:13"]
}, { }, {
"id": 1, "id": 1,
"usr": "c:@Foo1", "usr": "c:@Foo1",
@ -25,7 +23,8 @@ OUTPUT:
"qualified_name": "Foo1", "qualified_name": "Foo1",
"definition": "tests/usage/type_usage_typedef_and_using.cc:2:7", "definition": "tests/usage/type_usage_typedef_and_using.cc:2:7",
"alias_of": 0, "alias_of": 0,
"uses": ["tests/usage/type_usage_typedef_and_using.cc:7:14"] "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:2:7", "tests/usage/type_usage_typedef_and_using.cc:4:14", "tests/usage/type_usage_typedef_and_using.cc:7:14"],
"interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:4:14", "tests/usage/type_usage_typedef_and_using.cc:7:14"]
}, { }, {
"id": 2, "id": 2,
"usr": "c:type_usage_typedef_and_using.cc@T@Foo2", "usr": "c:type_usage_typedef_and_using.cc@T@Foo2",
@ -33,7 +32,8 @@ OUTPUT:
"qualified_name": "Foo2", "qualified_name": "Foo2",
"definition": "tests/usage/type_usage_typedef_and_using.cc:3:13", "definition": "tests/usage/type_usage_typedef_and_using.cc:3:13",
"alias_of": 0, "alias_of": 0,
"uses": ["tests/usage/type_usage_typedef_and_using.cc:8:14"] "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:3:13", "tests/usage/type_usage_typedef_and_using.cc:8:14"],
"interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:8:14"]
}, { }, {
"id": 3, "id": 3,
"usr": "c:@Foo3", "usr": "c:@Foo3",
@ -41,32 +41,37 @@ OUTPUT:
"qualified_name": "Foo3", "qualified_name": "Foo3",
"definition": "tests/usage/type_usage_typedef_and_using.cc:4:7", "definition": "tests/usage/type_usage_typedef_and_using.cc:4:7",
"alias_of": 1, "alias_of": 1,
"uses": ["tests/usage/type_usage_typedef_and_using.cc:9:14"] "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:4:7", "tests/usage/type_usage_typedef_and_using.cc:9:14"],
"interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:9:14"]
}], }],
"functions": [{ "functions": [{
"id": 0, "id": 0,
"usr": "c:@F@accept#*$@S@Foo#", "usr": "c:@F@accept#*$@S@Foo#",
"short_name": "accept", "short_name": "accept",
"qualified_name": "accept", "qualified_name": "accept",
"declaration": "tests/usage/type_usage_typedef_and_using.cc:6:6" "definition": "tests/usage/type_usage_typedef_and_using.cc:6:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:6:6"]
}, { }, {
"id": 1, "id": 1,
"usr": "c:@F@accept1#*$@S@Foo#", "usr": "c:@F@accept1#**$@S@Foo#",
"short_name": "accept1", "short_name": "accept1",
"qualified_name": "accept1", "qualified_name": "accept1",
"declaration": "tests/usage/type_usage_typedef_and_using.cc:7:6" "definition": "tests/usage/type_usage_typedef_and_using.cc:7:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:7:6"]
}, { }, {
"id": 2, "id": 2,
"usr": "c:@F@accept2#*$@S@Foo#", "usr": "c:@F@accept2#*$@S@Foo#",
"short_name": "accept2", "short_name": "accept2",
"qualified_name": "accept2", "qualified_name": "accept2",
"declaration": "tests/usage/type_usage_typedef_and_using.cc:8:6" "definition": "tests/usage/type_usage_typedef_and_using.cc:8:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:8:6"]
}, { }, {
"id": 3, "id": 3,
"usr": "c:@F@accept3#*$@S@Foo#", "usr": "c:@F@accept3#**$@S@Foo#",
"short_name": "accept3", "short_name": "accept3",
"qualified_name": "accept3", "qualified_name": "accept3",
"declaration": "tests/usage/type_usage_typedef_and_using.cc:9:6" "definition": "tests/usage/type_usage_typedef_and_using.cc:9:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:9:6"]
}], }],
"variables": [] "variables": []
} }