Browse Source

Fix indexing function call when there is implicit ctor call

pull/2/head
Jacob Dufault 8 years ago
parent
commit
abbc6380f4
  1. 24
      src/indexer.cc
  2. 3
      src/query.h
  3. 2
      src/test.cc
  4. 53
      tests/usage/func_called_implicit_ctor.cc

24
src/indexer.cc

@ -6,6 +6,17 @@
#include "platform.h" #include "platform.h"
#include "serializer.h" #include "serializer.h"
namespace {
void AddFuncRef(std::vector<IndexFuncRef>* 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) { IndexedFile::IndexedFile(const std::string& path) : id_cache(path), path(path) {
// TODO: Reconsider if we should still be reusing the same id_cache. // TODO: Reconsider if we should still be reusing the same id_cache.
// Preallocate any existing resolved ids. // Preallocate any existing resolved ids.
@ -192,10 +203,6 @@ struct IndexParam {
FileConsumer* file_consumer; FileConsumer* file_consumer;
NamespaceHelper ns; 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) {} IndexParam(FileConsumer* file_consumer) : file_consumer(file_consumer) {}
}; };
@ -1242,11 +1249,6 @@ void indexEntityReference(CXClientData client_data,
if (!loc_spelling) if (!loc_spelling)
break; 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. // Note: be careful, calling db->ToFuncId invalidates the FuncDef* ptrs.
IndexFuncId called_id = db->ToFuncId(ref->referencedEntity->USR); IndexFuncId called_id = db->ToFuncId(ref->referencedEntity->USR);
if (IsFunctionCallContext(ref->container->cursor.kind)) { if (IsFunctionCallContext(ref->container->cursor.kind)) {
@ -1254,8 +1256,8 @@ void indexEntityReference(CXClientData client_data,
IndexedFuncDef* caller_def = db->Resolve(caller_id); IndexedFuncDef* caller_def = db->Resolve(caller_id);
IndexedFuncDef* called_def = db->Resolve(called_id); IndexedFuncDef* called_def = db->Resolve(called_id);
caller_def->def.callees.push_back(IndexFuncRef(called_id, loc_spelling.value())); AddFuncRef(&caller_def->def.callees, IndexFuncRef(called_id, loc_spelling.value()));
called_def->callers.push_back(IndexFuncRef(caller_id, loc_spelling.value())); AddFuncRef(&called_def->callers, IndexFuncRef(caller_id, loc_spelling.value()));
AddUsage(called_def->uses, loc_spelling.value()); AddUsage(called_def->uses, loc_spelling.value());
} else { } else {
IndexedFuncDef* called_def = db->Resolve(called_id); IndexedFuncDef* called_def = db->Resolve(called_id);

3
src/query.h

@ -195,6 +195,9 @@ struct QueryableFuncDef {
DefUpdate def; DefUpdate def;
std::vector<QueryableLocation> declarations; std::vector<QueryableLocation> declarations;
std::vector<QueryFuncId> derived; std::vector<QueryFuncId> 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<QueryFuncRef> callers; std::vector<QueryFuncRef> callers;
std::vector<QueryableLocation> uses; std::vector<QueryableLocation> uses;
size_t qualified_name_idx = -1; size_t qualified_name_idx = -1;

2
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/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/header.h") continue;
//if (path != "tests/multi_file/simple_impl.cc") 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/templates/implicit_variable_instantiation.cc") continue;
//if (path != "tests/_empty_test.cc") continue; //if (path != "tests/_empty_test.cc") continue;

53
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"]
}]
}
*/
Loading…
Cancel
Save