From 3d0b8fd80714a13cdb7128d989ee7df4eafe4e5b Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Tue, 13 Jun 2017 23:50:30 -0700 Subject: [PATCH] Fix call tree when function ref does not refer to a function. --- src/command_line.cc | 32 ++++++++++++++++++++++---------- src/indexer.h | 1 + src/query.h | 24 ++++++++++-------------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/command_line.cc b/src/command_line.cc index 5e5eb864..c48a0819 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -892,19 +892,32 @@ NonElidedVector BuildExpandCallTree(QueryDatabase NonElidedVector result; result.reserve(root_func->callers.size()); for (QueryFuncRef caller : root_func->callers) { - optional& call_func = db->funcs[caller.id.id]; - if (!call_func) - continue; optional call_location = GetLsLocation(db, working_files, caller.loc); if (!call_location) continue; - Out_CqueryCallTree::CallEntry call_entry; - call_entry.name = call_func->def.short_name; - call_entry.usr = call_func->def.usr; - call_entry.location = *call_location; - call_entry.hasCallers = !call_func->callers.empty(); - result.push_back(call_entry); + if (caller.has_id()) { + optional& call_func = db->funcs[caller.id_.id]; + if (!call_func) + continue; + + Out_CqueryCallTree::CallEntry call_entry; + call_entry.name = call_func->def.short_name; + call_entry.usr = call_func->def.usr; + call_entry.location = *call_location; + call_entry.hasCallers = !call_func->callers.empty(); + result.push_back(call_entry); + } + else { + // TODO: See if we can do a better job here. Need more information from + // the indexer. + Out_CqueryCallTree::CallEntry call_entry; + call_entry.name = "Likely Constructor"; + call_entry.usr = "no_usr"; + call_entry.location = *call_location; + call_entry.hasCallers = false; + result.push_back(call_entry); + } } return result; @@ -1732,7 +1745,6 @@ bool IndexMain_DoCreateIndexUpdate( return false; Timer time; - // TODO/FIXME: Running call tree on IndexUpdate::CreateDelta crashes cquery. IndexUpdate update = IndexUpdate::CreateDelta(response->previous_id_map.get(), response->current_id_map.get(), response->previous_index.get(), response->current_index.get()); response->perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); diff --git a/src/indexer.h b/src/indexer.h index 1725e3fe..235dd887 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -78,6 +78,7 @@ struct IdCache; struct IndexFuncRef { + // NOTE: id can be -1 if the function call is not coming from a function. IndexFuncId id; Range loc; bool is_implicit = false; diff --git a/src/query.h b/src/query.h index 3ed5e98c..1b09f3c7 100644 --- a/src/query.h +++ b/src/query.h @@ -100,26 +100,29 @@ struct SymbolRef { MAKE_REFLECT_STRUCT(SymbolRef, idx, loc); struct QueryFuncRef { - QueryFuncId id; + // NOTE: id_ can be -1 if the function call is not coming from a function. + QueryFuncId id_; QueryLocation loc; bool is_implicit = false; + bool has_id() const { return id_.id != -1; } + QueryFuncRef() {} // Do not use, needed for reflect. - QueryFuncRef(QueryFuncId id, QueryLocation loc, bool is_implicit) : id(id), loc(loc), is_implicit(is_implicit) {} + QueryFuncRef(QueryFuncId id, QueryLocation loc, bool is_implicit) : id_(id), loc(loc), is_implicit(is_implicit) {} bool operator==(const QueryFuncRef& that) const { - return id == that.id && loc == that.loc && is_implicit == that.is_implicit; + return id_ == that.id_ && loc == that.loc && is_implicit == that.is_implicit; } bool operator!=(const QueryFuncRef& that) const { return !(*this == that); } bool operator<(const QueryFuncRef& that) const { - if (id < that.id) + if (id_ < that.id_) return true; - if (id == that.id && loc.range.start < that.loc.range.start) + if (id_ == that.id_ && loc.range.start < that.loc.range.start) return true; - return id == that.id && loc.range.start == that.loc.range.start && is_implicit < that.is_implicit; + return id_ == that.id_ && loc.range.start == that.loc.range.start && is_implicit < that.is_implicit; } }; -MAKE_REFLECT_STRUCT(QueryFuncRef, id, loc, is_implicit); +MAKE_REFLECT_STRUCT(QueryFuncRef, id_, loc, is_implicit); // There are two sources of reindex updates: the (single) definition of a // symbol has changed, or one of many users of the symbol has changed. @@ -298,13 +301,6 @@ struct QueryDatabase { struct IdMap { - // TODO threading model - // - [querydb] Create IdMap mapping from every id registered in local_ids - // - [indexer] Create IndexUpdate using IdMap cached state - // - [querydb] Apply IndexUpdate - // - // Then lookup in cached_* should *never* fail. - const IdCache& local_ids; QueryFileId primary_file;