From f3edc6e2f010cf0eabe5605549b8e33e22891af4 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Mon, 20 Feb 2017 14:06:50 -0800 Subject: [PATCH] using-for-generic-types --- main.cpp | 30 +++++++------- tests/usage/type_usage_typedef_and_using.cc | 40 +++++++++++-------- .../type_usage_typedef_and_using_template.cc | 36 +++++++++++++++++ 3 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 tests/usage/type_usage_typedef_and_using_template.cc diff --git a/main.cpp b/main.cpp index 49818a4a..5e02f363 100644 --- a/main.cpp +++ b/main.cpp @@ -732,7 +732,9 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(clang::Cursor cursor, clang::C return clang::VisiterResult::Continue; } -std::optional ResolveDeclToType(ParsingDatabase* db, clang::Cursor decl_cursor, const CXIdxContainerInfo* semantic_container, const CXIdxContainerInfo* lexical_container, bool is_interesting) { +std::optional 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: // @@ -781,7 +783,8 @@ std::optional ResolveDeclToType(ParsingDatabase* db, clang::Cursor decl_ // children, the first one will always be visited. if (param.previous_cursor && process_last_type_ref) { VisitDeclForTypeUsageVisitorHandler(param.previous_cursor.value(), ¶m); - } else { + } + else { // If we are not processing the last type ref, it *must* be a TypeRef (ie, // and not a TemplateRef). 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); - std::optional var_type = ResolveDeclToType(db, decl_cursor, decl->semanticContainer, decl->lexicalContainer, decl_cursor.get_kind() != CXCursor_ParmDecl); + std::optional var_type = ResolveDeclToType(db, decl_cursor, decl_cursor.get_kind() != CXCursor_ParmDecl /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer); if (var_type.has_value()) var_def->variable_type = var_type.value(); // 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 // 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()); //if (ret_type.resolved_type) @@ -918,7 +921,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { case CXCursor_ParmDecl: // We don't need to know the arg type, but we do want to mark it as // 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()); //if (arg_type.resolved_type) @@ -965,24 +968,19 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) { case CXIdxEntity_Typedef: case CXIdxEntity_CXXTypeAlias: { + std::optional alias_of = ResolveDeclToType(db, decl->cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer); + TypeId type_id = db->ToTypeId(decl->entityInfo->USR); - - std::optional 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()); + if (alias_of) + type_def->alias_of = alias_of.value(); 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; } @@ -1159,7 +1157,7 @@ ParsingDatabase Parse(std::string filename) { clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/); clang::TranslationUnit tu(index, filename, args); - //Dump(tu.document_cursor()); + Dump(tu.document_cursor()); 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")) { //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/destructor.cc") continue; //if (path == "tests/usage/func_usage_call_method.cc") continue; diff --git a/tests/usage/type_usage_typedef_and_using.cc b/tests/usage/type_usage_typedef_and_using.cc index 78051cb9..10c1c391 100644 --- a/tests/usage/type_usage_typedef_and_using.cc +++ b/tests/usage/type_usage_typedef_and_using.cc @@ -2,6 +2,7 @@ struct Foo; using Foo1 = Foo*; typedef Foo Foo2; using Foo3 = Foo1; +using Foo4 = int; void accept(Foo*) {} void accept1(Foo1*) {} @@ -14,8 +15,8 @@ OUTPUT: "types": [{ "id": 0, "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"], - "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"] + "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:7:13"] }, { "id": 1, "usr": "c:@Foo1", @@ -23,8 +24,8 @@ OUTPUT: "qualified_name": "Foo1", "definition": "tests/usage/type_usage_typedef_and_using.cc:2:7", "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"], - "interesting_uses": ["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:8:14"] }, { "id": 2, "usr": "c:type_usage_typedef_and_using.cc@T@Foo2", @@ -32,8 +33,8 @@ OUTPUT: "qualified_name": "Foo2", "definition": "tests/usage/type_usage_typedef_and_using.cc:3:13", "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"], - "interesting_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:9:14"], + "interesting_uses": ["tests/usage/type_usage_typedef_and_using.cc:9:14"] }, { "id": 3, "usr": "c:@Foo3", @@ -41,37 +42,44 @@ OUTPUT: "qualified_name": "Foo3", "definition": "tests/usage/type_usage_typedef_and_using.cc:4:7", "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"], - "interesting_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:10: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": [{ "id": 0, "usr": "c:@F@accept#*$@S@Foo#", "short_name": "accept", "qualified_name": "accept", - "definition": "tests/usage/type_usage_typedef_and_using.cc:6:6", - "all_uses": ["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:7:6"] }, { "id": 1, "usr": "c:@F@accept1#**$@S@Foo#", "short_name": "accept1", "qualified_name": "accept1", - "definition": "tests/usage/type_usage_typedef_and_using.cc:7:6", - "all_uses": ["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:8:6"] }, { "id": 2, "usr": "c:@F@accept2#*$@S@Foo#", "short_name": "accept2", "qualified_name": "accept2", - "definition": "tests/usage/type_usage_typedef_and_using.cc:8:6", - "all_uses": ["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:9:6"] }, { "id": 3, "usr": "c:@F@accept3#**$@S@Foo#", "short_name": "accept3", "qualified_name": "accept3", - "definition": "tests/usage/type_usage_typedef_and_using.cc:9:6", - "all_uses": ["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:10:6"] }], "variables": [] } diff --git a/tests/usage/type_usage_typedef_and_using_template.cc b/tests/usage/type_usage_typedef_and_using_template.cc new file mode 100644 index 00000000..7bf2fa8f --- /dev/null +++ b/tests/usage/type_usage_typedef_and_using_template.cc @@ -0,0 +1,36 @@ +template +struct Foo; + +using Foo1 = Foo; +typedef Foo 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": [] +} +*/ \ No newline at end of file