using-for-generic-types

This commit is contained in:
Jacob Dufault 2017-02-20 14:06:50 -08:00
parent 561f747133
commit f3edc6e2f0
3 changed files with 74 additions and 32 deletions

View File

@ -732,7 +732,9 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(clang::Cursor cursor, clang::C
return clang::VisiterResult::Continue; return clang::VisiterResult::Continue;
} }
std::optional<TypeId> ResolveDeclToType(ParsingDatabase* db, clang::Cursor decl_cursor, const CXIdxContainerInfo* semantic_container, const CXIdxContainerInfo* lexical_container, bool is_interesting) { std::optional<TypeId> ResolveDeclToType(ParsingDatabase* db, clang::Cursor decl_cursor,
bool is_interesting, const CXIdxContainerInfo* semantic_container,
const CXIdxContainerInfo* lexical_container) {
// //
// The general AST format for definitions follows this pattern: // The general AST format for definitions follows this pattern:
// //
@ -781,7 +783,8 @@ std::optional<TypeId> ResolveDeclToType(ParsingDatabase* db, clang::Cursor decl_
// children, the first one will always be visited. // children, the first one will always be visited.
if (param.previous_cursor && process_last_type_ref) { if (param.previous_cursor && process_last_type_ref) {
VisitDeclForTypeUsageVisitorHandler(param.previous_cursor.value(), &param); VisitDeclForTypeUsageVisitorHandler(param.previous_cursor.value(), &param);
} else { }
else {
// If we are not processing the last type ref, it *must* be a TypeRef (ie, // If we are not processing the last type ref, it *must* be a TypeRef (ie,
// and not a TemplateRef). // and not a TemplateRef).
assert(!param.previous_cursor.has_value() || assert(!param.previous_cursor.has_value() ||
@ -827,7 +830,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
var_def->all_uses.push_back(decl->loc); var_def->all_uses.push_back(decl->loc);
std::optional<TypeId> var_type = ResolveDeclToType(db, decl_cursor, decl->semanticContainer, decl->lexicalContainer, decl_cursor.get_kind() != CXCursor_ParmDecl); std::optional<TypeId> var_type = ResolveDeclToType(db, decl_cursor, decl_cursor.get_kind() != CXCursor_ParmDecl /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
if (var_type.has_value()) if (var_type.has_value())
var_def->variable_type = var_type.value(); var_def->variable_type = var_type.value();
// Declaring variable type information. // Declaring variable type information.
@ -896,7 +899,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// We don't actually need to know the return type, but we need to mark it // We don't actually need to know the return type, but we need to mark it
// as an interesting usage. // as an interesting usage.
ResolveDeclToType(db, decl_cursor, decl->semanticContainer, decl->lexicalContainer, true /*is_interesting*/); ResolveDeclToType(db, decl_cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
//TypeResolution ret_type = ResolveToType(db, decl_cursor.get_type().get_return_type()); //TypeResolution ret_type = ResolveToType(db, decl_cursor.get_type().get_return_type());
//if (ret_type.resolved_type) //if (ret_type.resolved_type)
@ -918,7 +921,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
case CXCursor_ParmDecl: case CXCursor_ParmDecl:
// We don't need to know the arg type, but we do want to mark it as // We don't need to know the arg type, but we do want to mark it as
// an interesting usage. // an interesting usage.
ResolveDeclToType(db, arg, decl->semanticContainer, decl->lexicalContainer, true /*is_interesting*/); ResolveDeclToType(db, arg, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
//TypeResolution arg_type = ResolveToType(db, arg.get_type()); //TypeResolution arg_type = ResolveToType(db, arg.get_type());
//if (arg_type.resolved_type) //if (arg_type.resolved_type)
@ -965,24 +968,19 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
case CXIdxEntity_Typedef: case CXIdxEntity_Typedef:
case CXIdxEntity_CXXTypeAlias: case CXIdxEntity_CXXTypeAlias:
{ {
std::optional<TypeId> alias_of = ResolveDeclToType(db, decl->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
TypeId type_id = db->ToTypeId(decl->entityInfo->USR); 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); TypeDef* type_def = db->Resolve(type_id);
type_def->alias_of = alias_of; if (alias_of)
db->Resolve(alias_of)->interesting_uses.push_back(type_ref.value().get_source_location()); type_def->alias_of = alias_of.value();
type_def->short_name = decl->entityInfo->name; type_def->short_name = decl->entityInfo->name;
type_def->qualified_name = ns->QualifiedName(decl->semanticContainer, type_def->short_name); type_def->qualified_name = ns->QualifiedName(decl->semanticContainer, type_def->short_name);
type_def->definition = decl->loc; type_def->definition = decl->loc;
type_def->all_uses.push_back(decl->loc); type_def->all_uses.push_back(decl->loc);
break; break;
} }
@ -1159,7 +1157,7 @@ ParsingDatabase Parse(std::string filename) {
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/); clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
clang::TranslationUnit tu(index, filename, args); clang::TranslationUnit tu(index, filename, args);
//Dump(tu.document_cursor()); Dump(tu.document_cursor());
CXIndexAction index_action = clang_IndexAction_create(index.cx_index); CXIndexAction index_action = clang_IndexAction_create(index.cx_index);
@ -1285,7 +1283,7 @@ int main(int argc, char** argv) {
for (std::string path : GetFilesInFolder("tests")) { for (std::string path : GetFilesInFolder("tests")) {
//if (path != "tests/declaration_vs_definition/class_member_static.cc") continue; //if (path != "tests/declaration_vs_definition/class_member_static.cc") continue;
//if (path != "tests/usage/type_usage_declare_param.cc") continue; //if (path != "tests/usage/type_usage_typedef_and_using_template.cc") continue;
//if (path == "tests/constructors/constructor.cc") continue; //if (path == "tests/constructors/constructor.cc") continue;
//if (path == "tests/constructors/destructor.cc") continue; //if (path == "tests/constructors/destructor.cc") continue;
//if (path == "tests/usage/func_usage_call_method.cc") continue; //if (path == "tests/usage/func_usage_call_method.cc") continue;

View File

@ -2,6 +2,7 @@ struct Foo;
using Foo1 = Foo*; using Foo1 = Foo*;
typedef Foo Foo2; typedef Foo Foo2;
using Foo3 = Foo1; using Foo3 = Foo1;
using Foo4 = int;
void accept(Foo*) {} void accept(Foo*) {}
void accept1(Foo1*) {} void accept1(Foo1*) {}
@ -14,8 +15,8 @@ OUTPUT:
"types": [{ "types": [{
"id": 0, "id": 0,
"usr": "c:@S@Foo", "usr": "c:@S@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"], "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:7:13"],
"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"] "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:7:13"]
}, { }, {
"id": 1, "id": 1,
"usr": "c:@Foo1", "usr": "c:@Foo1",
@ -23,8 +24,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,
"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"], "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:8:14"],
"interesting_uses": ["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:8: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",
@ -32,8 +33,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,
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:3:13", "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:9:14"],
"interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:8:14"] "interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:9:14"]
}, { }, {
"id": 3, "id": 3,
"usr": "c:@Foo3", "usr": "c:@Foo3",
@ -41,37 +42,44 @@ 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,
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:4:7", "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:10:14"],
"interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:9:14"] "interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:10:14"]
}, {
"id": 4,
"usr": "c:@Foo4",
"short_name": "Foo4",
"qualified_name": "Foo4",
"definition": "tests/usage/type_usage_typedef_and_using.cc:5:7",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:5:7"]
}], }],
"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",
"definition": "tests/usage/type_usage_typedef_and_using.cc:6:6", "definition": "tests/usage/type_usage_typedef_and_using.cc:7:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:6:6"] "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:7: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",
"definition": "tests/usage/type_usage_typedef_and_using.cc:7:6", "definition": "tests/usage/type_usage_typedef_and_using.cc:8:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:7:6"] "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:8: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",
"definition": "tests/usage/type_usage_typedef_and_using.cc:8:6", "definition": "tests/usage/type_usage_typedef_and_using.cc:9:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:8:6"] "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:9: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",
"definition": "tests/usage/type_usage_typedef_and_using.cc:9:6", "definition": "tests/usage/type_usage_typedef_and_using.cc:10:6",
"all_uses": ["tests/usage/type_usage_typedef_and_using.cc:9:6"] "all_uses": ["tests/usage/type_usage_typedef_and_using.cc:10:6"]
}], }],
"variables": [] "variables": []
} }

View File

@ -0,0 +1,36 @@
template<typename T>
struct Foo;
using Foo1 = Foo<int>;
typedef Foo<Foo1> Foo2;
/*
OUTPUT:
{
"types": [{
"id": 0,
"usr": "c:@ST>1#T@Foo",
"all_uses": ["tests/usage/type_usage_typedef_and_using_template.cc:2:8", "tests/usage/type_usage_typedef_and_using_template.cc:4:14", "tests/usage/type_usage_typedef_and_using_template.cc:5:9"],
"interesting_uses": ["tests/usage/type_usage_typedef_and_using_template.cc:4:14", "tests/usage/type_usage_typedef_and_using_template.cc:5:9"]
}, {
"id": 1,
"usr": "c:@Foo1",
"short_name": "Foo1",
"qualified_name": "Foo1",
"definition": "tests/usage/type_usage_typedef_and_using_template.cc:4:7",
"alias_of": 0,
"all_uses": ["tests/usage/type_usage_typedef_and_using_template.cc:4:7", "tests/usage/type_usage_typedef_and_using_template.cc:5:13"],
"interesting_uses": ["tests/usage/type_usage_typedef_and_using_template.cc:5:13"]
}, {
"id": 2,
"usr": "c:type_usage_typedef_and_using_template.cc@T@Foo2",
"short_name": "Foo2",
"qualified_name": "Foo2",
"definition": "tests/usage/type_usage_typedef_and_using_template.cc:5:19",
"alias_of": 0,
"all_uses": ["tests/usage/type_usage_typedef_and_using_template.cc:5:19"]
}],
"functions": [],
"variables": []
}
*/