From abbc6380f4ba8839eb2b1361b953dba6a8b3d9b3 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Wed, 12 Apr 2017 00:36:17 -0700 Subject: [PATCH] Fix indexing function call when there is implicit ctor call --- src/indexer.cc | 24 ++++++----- src/query.h | 3 ++ src/test.cc | 2 +- tests/usage/func_called_implicit_ctor.cc | 53 ++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 tests/usage/func_called_implicit_ctor.cc diff --git a/src/indexer.cc b/src/indexer.cc index 69e82cab..8ee9124f 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -6,6 +6,17 @@ #include "platform.h" #include "serializer.h" +namespace { + +void AddFuncRef(std::vector* result, IndexFuncRef ref) { + if (!result->empty() && (*result)[result->size() - 1] == ref) + return; + result->push_back(ref); +} + +} // namespace + + IndexedFile::IndexedFile(const std::string& path) : id_cache(path), path(path) { // TODO: Reconsider if we should still be reusing the same id_cache. // Preallocate any existing resolved ids. @@ -192,10 +203,6 @@ struct IndexParam { FileConsumer* file_consumer; NamespaceHelper ns; - // Record last func usage we reported, as clang will record the reference - // twice. We don't want to double report. - Range last_func_usage_location; - IndexParam(FileConsumer* file_consumer) : file_consumer(file_consumer) {} }; @@ -1242,11 +1249,6 @@ void indexEntityReference(CXClientData client_data, if (!loc_spelling) break; - // Don't report duplicate usages. - if (param->last_func_usage_location == loc_spelling.value()) - break; - param->last_func_usage_location = loc_spelling.value(); - // Note: be careful, calling db->ToFuncId invalidates the FuncDef* ptrs. IndexFuncId called_id = db->ToFuncId(ref->referencedEntity->USR); if (IsFunctionCallContext(ref->container->cursor.kind)) { @@ -1254,8 +1256,8 @@ void indexEntityReference(CXClientData client_data, IndexedFuncDef* caller_def = db->Resolve(caller_id); IndexedFuncDef* called_def = db->Resolve(called_id); - caller_def->def.callees.push_back(IndexFuncRef(called_id, loc_spelling.value())); - called_def->callers.push_back(IndexFuncRef(caller_id, loc_spelling.value())); + AddFuncRef(&caller_def->def.callees, IndexFuncRef(called_id, loc_spelling.value())); + AddFuncRef(&called_def->callers, IndexFuncRef(caller_id, loc_spelling.value())); AddUsage(called_def->uses, loc_spelling.value()); } else { IndexedFuncDef* called_def = db->Resolve(called_id); diff --git a/src/query.h b/src/query.h index bf4f5277..c4ea29ea 100644 --- a/src/query.h +++ b/src/query.h @@ -195,6 +195,9 @@ struct QueryableFuncDef { DefUpdate def; std::vector declarations; std::vector derived; + // TODO: It seems like callers is always the same as uses except callers does + // not include the definition or declaration. We should get a large space + // saving by removing it. std::vector callers; std::vector uses; size_t qualified_name_idx = -1; diff --git a/src/test.cc b/src/test.cc index f1287a55..7fd069b4 100644 --- a/src/test.cc +++ b/src/test.cc @@ -119,7 +119,7 @@ void RunTests() { //if (path != "tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc") continue; //if (path != "tests/multi_file/header.h") continue; //if (path != "tests/multi_file/simple_impl.cc") continue; - //if (path != "tests/usage/func_called_from_template.cc") continue; + //if (path != "tests/usage/func_called_implicit_ctor.cc") continue; //if (path != "tests/templates/implicit_variable_instantiation.cc") continue; //if (path != "tests/_empty_test.cc") continue; diff --git a/tests/usage/func_called_implicit_ctor.cc b/tests/usage/func_called_implicit_ctor.cc new file mode 100644 index 00000000..3e077cb5 --- /dev/null +++ b/tests/usage/func_called_implicit_ctor.cc @@ -0,0 +1,53 @@ +struct Wrapper { + Wrapper(int i); +}; + +int called() { return 1; } + +Wrapper caller() { + return called(); +} + +/* +OUTPUT: +{ + "types": [{ + "id": 0, + "usr": "c:@S@Wrapper", + "short_name": "Wrapper", + "qualified_name": "Wrapper", + "definition_spelling": "1:8-1:15", + "definition_extent": "1:1-3:2", + "funcs": [0], + "uses": ["*1:8-1:15", "2:3-2:10", "*7:1-7:8"] + }], + "funcs": [{ + "id": 0, + "usr": "c:@S@Wrapper@F@Wrapper#I#", + "short_name": "Wrapper", + "qualified_name": "Wrapper::Wrapper", + "declarations": ["2:3-2:10"], + "declaring_type": 0, + "callers": ["2@8:10-8:16"], + "uses": ["2:3-2:10", "8:10-8:16"] + }, { + "id": 1, + "usr": "c:@F@called#", + "short_name": "called", + "qualified_name": "called", + "definition_spelling": "5:5-5:11", + "definition_extent": "5:1-5:27", + "callers": ["2@8:10-8:16"], + "uses": ["5:5-5:11", "8:10-8:16"] + }, { + "id": 2, + "usr": "c:@F@caller#", + "short_name": "caller", + "qualified_name": "caller", + "definition_spelling": "7:9-7:15", + "definition_extent": "7:1-9:2", + "callees": ["0@8:10-8:16", "1@8:10-8:16"], + "uses": ["7:9-7:15"] + }] +} +*/