mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 20:12:33 +00:00
Remove concept of 'interesting' usage.
It never worked well enough. Showing variable instantations for the type will be more useful.
This commit is contained in:
parent
3ce446d202
commit
95b567838c
@ -446,7 +446,7 @@ optional<QueryLocation> GetDefinitionExtentOfSymbol(QueryDatabase* db, const Sym
|
|||||||
switch (symbol.kind) {
|
switch (symbol.kind) {
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
// TODO: If line 1 is deleted the file won't show up in, ie, workspace symbol search results.
|
// TODO: If line 1 is deleted the file won't show up in, ie, workspace symbol search results.
|
||||||
return QueryLocation(QueryFileId(symbol.idx), Range(false /*is_interesting*/, Position(1, 1), Position(1, 1)));
|
return QueryLocation(QueryFileId(symbol.idx), Range(Position(1, 1), Position(1, 1)));
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
return db->types[symbol.idx].def.definition_extent;
|
return db->types[symbol.idx].def.definition_extent;
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
@ -620,8 +620,7 @@ void AddCodeLens(
|
|||||||
const std::vector<QueryLocation>& uses,
|
const std::vector<QueryLocation>& uses,
|
||||||
const char* singular,
|
const char* singular,
|
||||||
const char* plural,
|
const char* plural,
|
||||||
bool exclude_loc = false,
|
bool exclude_loc = false) {
|
||||||
bool only_interesting = false) {
|
|
||||||
TCodeLens code_lens;
|
TCodeLens code_lens;
|
||||||
optional<lsRange> range = GetLsRange(common->working_file, loc.range);
|
optional<lsRange> range = GetLsRange(common->working_file, loc.range);
|
||||||
if (!range)
|
if (!range)
|
||||||
@ -637,8 +636,6 @@ void AddCodeLens(
|
|||||||
for (const QueryLocation& use : uses) {
|
for (const QueryLocation& use : uses) {
|
||||||
if (exclude_loc && use == loc)
|
if (exclude_loc && use == loc)
|
||||||
continue;
|
continue;
|
||||||
if (only_interesting && !use.range.interesting)
|
|
||||||
continue;
|
|
||||||
optional<lsLocation> location = GetLsLocation(common->db, common->working_files, use);
|
optional<lsLocation> location = GetLsLocation(common->db, common->working_files, use);
|
||||||
if (!location)
|
if (!location)
|
||||||
continue;
|
continue;
|
||||||
@ -1440,9 +1437,8 @@ void QueryDbMainLoop(
|
|||||||
case SymbolKind::Type: {
|
case SymbolKind::Type: {
|
||||||
QueryType& type = db->types[symbol.idx];
|
QueryType& type = db->types[symbol.idx];
|
||||||
AddCodeLens(&common, ref.loc.OffsetStartColumn(0), type.uses, "ref", "refs");
|
AddCodeLens(&common, ref.loc.OffsetStartColumn(0), type.uses, "ref", "refs");
|
||||||
AddCodeLens(&common, ref.loc.OffsetStartColumn(1), type.uses, "iref", "irefs", false /*exclude_loc*/, true /*only_interesting*/);
|
AddCodeLens(&common, ref.loc.OffsetStartColumn(1), ToQueryLocation(db, type.derived), "derived", "derived");
|
||||||
AddCodeLens(&common, ref.loc.OffsetStartColumn(2), ToQueryLocation(db, type.derived), "derived", "derived");
|
AddCodeLens(&common, ref.loc.OffsetStartColumn(2), ToQueryLocation(db, type.instantiations), "instantiation", "instantiations");
|
||||||
AddCodeLens(&common, ref.loc.OffsetStartColumn(3), ToQueryLocation(db, type.instantiations), "instantiation", "instantiations");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
@ -1491,7 +1487,7 @@ void QueryDbMainLoop(
|
|||||||
}
|
}
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
QueryVar& var = db->vars[symbol.idx];
|
QueryVar& var = db->vars[symbol.idx];
|
||||||
AddCodeLens(&common, ref.loc.OffsetStartColumn(0), var.uses, "ref", "refs", true /*exclude_loc*/, false /*only_interesting*/);
|
AddCodeLens(&common, ref.loc.OffsetStartColumn(0), var.uses, "ref", "refs", true /*exclude_loc*/);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolKind::File:
|
case SymbolKind::File:
|
||||||
|
154
src/indexer.cc
154
src/indexer.cc
@ -97,47 +97,26 @@ IndexedTypeDef::IndexedTypeDef(IndexTypeId id, const std::string& usr)
|
|||||||
// std::cerr << "Creating type with usr " << usr << std::endl;
|
// std::cerr << "Creating type with usr " << usr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveItem(std::vector<Range>& ranges,
|
void RemoveItem(std::vector<Range>& ranges, Range to_remove) {
|
||||||
Range to_remove) {
|
|
||||||
auto it = std::find(ranges.begin(), ranges.end(), to_remove);
|
auto it = std::find(ranges.begin(), ranges.end(), to_remove);
|
||||||
if (it != ranges.end())
|
if (it != ranges.end())
|
||||||
ranges.erase(it);
|
ranges.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniqueAdd(std::vector<IndexFuncRef>& refs,
|
void UniqueAdd(std::vector<IndexFuncRef>& refs, IndexFuncRef ref) {
|
||||||
IndexFuncRef ref) {
|
|
||||||
if (std::find(refs.begin(), refs.end(), ref) != refs.end())
|
if (std::find(refs.begin(), refs.end(), ref) != refs.end())
|
||||||
refs.push_back(ref);
|
refs.push_back(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniqueAdd(std::vector<Range>& uses,
|
void UniqueAdd(std::vector<Range>& uses, Range loc) {
|
||||||
Range loc,
|
if (std::find(uses.begin(), uses.end(), loc) == uses.end())
|
||||||
bool insert_if_not_present = true) {
|
|
||||||
// cannot sub 1 from size_t in loop below; check explicitly here
|
|
||||||
if (uses.empty()) {
|
|
||||||
if (insert_if_not_present)
|
|
||||||
uses.push_back(loc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: think about if we need to also consider |uses[i].end|
|
|
||||||
// First thought makes me think no, we don't.
|
|
||||||
for (int i = uses.size() - 1; i >= 0; --i) {
|
|
||||||
if (uses[i].start == loc.start) {
|
|
||||||
if (loc.interesting)
|
|
||||||
uses[i].interesting = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insert_if_not_present)
|
|
||||||
uses.push_back(loc);
|
uses.push_back(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
IdCache::IdCache(const std::string& primary_file)
|
IdCache::IdCache(const std::string& primary_file)
|
||||||
: primary_file(primary_file) {}
|
: primary_file(primary_file) {}
|
||||||
|
|
||||||
Range IdCache::Resolve(const CXSourceRange& range, bool interesting) {
|
Range IdCache::Resolve(const CXSourceRange& range) {
|
||||||
CXSourceLocation start = clang_getRangeStart(range);
|
CXSourceLocation start = clang_getRangeStart(range);
|
||||||
CXSourceLocation end = clang_getRangeEnd(range);
|
CXSourceLocation end = clang_getRangeEnd(range);
|
||||||
|
|
||||||
@ -146,19 +125,19 @@ Range IdCache::Resolve(const CXSourceRange& range, bool interesting) {
|
|||||||
unsigned int end_line, end_column;
|
unsigned int end_line, end_column;
|
||||||
clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr);
|
clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr);
|
||||||
|
|
||||||
return Range(interesting,
|
return Range(
|
||||||
Position(start_line, start_column) /*start*/,
|
Position(start_line, start_column) /*start*/,
|
||||||
Position(end_line, end_column) /*end*/);
|
Position(end_line, end_column) /*end*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
Range IdCache::ResolveSpelling(const CXCursor& cx_cursor, bool interesting) {
|
Range IdCache::ResolveSpelling(const CXCursor& cx_cursor) {
|
||||||
CXSourceRange cx_range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0);
|
CXSourceRange cx_range = clang_Cursor_getSpellingNameRange(cx_cursor, 0, 0);
|
||||||
return Resolve(cx_range, interesting);
|
return Resolve(cx_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
Range IdCache::ResolveExtent(const CXCursor& cx_cursor, bool interesting) {
|
Range IdCache::ResolveExtent(const CXCursor& cx_cursor) {
|
||||||
CXSourceRange cx_range = clang_getCursorExtent(cx_cursor);
|
CXSourceRange cx_range = clang_getCursorExtent(cx_cursor);
|
||||||
return Resolve(cx_range, interesting);
|
return Resolve(cx_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -358,13 +337,11 @@ bool IsTypeDefinition(const CXIdxContainerInfo* container) {
|
|||||||
|
|
||||||
struct VisitDeclForTypeUsageParam {
|
struct VisitDeclForTypeUsageParam {
|
||||||
IndexedFile* db;
|
IndexedFile* db;
|
||||||
bool is_interesting;
|
|
||||||
int has_processed_any = false;
|
int has_processed_any = false;
|
||||||
optional<clang::Cursor> previous_cursor;
|
optional<clang::Cursor> previous_cursor;
|
||||||
optional<IndexTypeId> initial_type;
|
optional<IndexTypeId> initial_type;
|
||||||
|
|
||||||
VisitDeclForTypeUsageParam(IndexedFile* db, bool is_interesting)
|
VisitDeclForTypeUsageParam(IndexedFile* db) : db(db) {}
|
||||||
: db(db), is_interesting(is_interesting) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor,
|
void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor,
|
||||||
@ -385,13 +362,11 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor,
|
|||||||
if (!param->initial_type)
|
if (!param->initial_type)
|
||||||
param->initial_type = ref_type_id;
|
param->initial_type = ref_type_id;
|
||||||
|
|
||||||
if (param->is_interesting) {
|
|
||||||
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
|
IndexedTypeDef* ref_type_def = db->Resolve(ref_type_id);
|
||||||
// TODO: Should we even be visiting this if the file is not from the main
|
// TODO: Should we even be visiting this if the file is not from the main
|
||||||
// def? Try adding assert on |loc| later.
|
// def? Try adding assert on |loc| later.
|
||||||
Range loc = db->id_cache.ResolveSpelling(cursor.cx_cursor, true /*interesting*/);
|
Range loc = db->id_cache.ResolveSpelling(cursor.cx_cursor);
|
||||||
UniqueAdd(ref_type_def->uses, loc);
|
UniqueAdd(ref_type_def->uses, loc);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
||||||
@ -404,16 +379,6 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
|||||||
if (param->previous_cursor) {
|
if (param->previous_cursor) {
|
||||||
VisitDeclForTypeUsageVisitorHandler(param->previous_cursor.value(),
|
VisitDeclForTypeUsageVisitorHandler(param->previous_cursor.value(),
|
||||||
param);
|
param);
|
||||||
|
|
||||||
// This if is inside the above if because if there are multiple
|
|
||||||
// TypeRefs,
|
|
||||||
// we always want to process the first one. If we did not always process
|
|
||||||
// the first one, we cannot tell if there are more TypeRefs after it and
|
|
||||||
// logic for fetching the return type breaks. This happens in ParmDecl
|
|
||||||
// instances which only have one TypeRef child but are not interesting
|
|
||||||
// usages.
|
|
||||||
if (!param->is_interesting)
|
|
||||||
return clang::VisiterResult::Break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
param->previous_cursor = cursor;
|
param->previous_cursor = cursor;
|
||||||
@ -461,9 +426,9 @@ optional<IndexTypeId> ResolveToDeclarationType(IndexedFile* db,
|
|||||||
optional<IndexTypeId> AddDeclTypeUsages(
|
optional<IndexTypeId> AddDeclTypeUsages(
|
||||||
IndexedFile* db,
|
IndexedFile* db,
|
||||||
clang::Cursor decl_cursor,
|
clang::Cursor decl_cursor,
|
||||||
bool is_interesting,
|
|
||||||
const CXIdxContainerInfo* semantic_container,
|
const CXIdxContainerInfo* semantic_container,
|
||||||
const CXIdxContainerInfo* lexical_container) {
|
const CXIdxContainerInfo* lexical_container) {
|
||||||
|
|
||||||
// std::cerr << std::endl << "AddDeclUsages " << decl_cursor.get_spelling() <<
|
// std::cerr << std::endl << "AddDeclUsages " << decl_cursor.get_spelling() <<
|
||||||
// std::endl;
|
// std::endl;
|
||||||
// Dump(decl_cursor);
|
// Dump(decl_cursor);
|
||||||
@ -569,7 +534,7 @@ optional<IndexTypeId> AddDeclTypeUsages(
|
|||||||
process_last_type_ref = false;
|
process_last_type_ref = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VisitDeclForTypeUsageParam param(db, is_interesting);
|
VisitDeclForTypeUsageParam param(db);
|
||||||
decl_cursor.VisitChildren(&VisitDeclForTypeUsageVisitor, ¶m);
|
decl_cursor.VisitChildren(&VisitDeclForTypeUsageVisitor, ¶m);
|
||||||
|
|
||||||
// VisitDeclForTypeUsageVisitor guarantees that if there are multiple TypeRef
|
// VisitDeclForTypeUsageVisitor guarantees that if there are multiple TypeRef
|
||||||
@ -583,8 +548,7 @@ optional<IndexTypeId> AddDeclTypeUsages(
|
|||||||
// We will not visit every child if the is_interseting is false, so
|
// We will not visit every child if the is_interseting is false, so
|
||||||
// previous_cursor
|
// previous_cursor
|
||||||
// may not point to the last TemplateRef.
|
// may not point to the last TemplateRef.
|
||||||
assert(is_interesting == false ||
|
assert(param.previous_cursor.has_value() == false ||
|
||||||
param.previous_cursor.has_value() == false ||
|
|
||||||
(param.previous_cursor.value().get_kind() == CXCursor_TypeRef ||
|
(param.previous_cursor.value().get_kind() == CXCursor_TypeRef ||
|
||||||
param.previous_cursor.value().get_kind() == CXCursor_TemplateRef));
|
param.previous_cursor.value().get_kind() == CXCursor_TemplateRef));
|
||||||
}
|
}
|
||||||
@ -638,7 +602,7 @@ clang::VisiterResult AddDeclInitializerUsagesVisitor(clang::Cursor cursor,
|
|||||||
if (ref_usr == "")
|
if (ref_usr == "")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Range loc = db->id_cache.ResolveSpelling(cursor.cx_cursor, false /*interesting*/);
|
Range loc = db->id_cache.ResolveSpelling(cursor.cx_cursor);
|
||||||
// std::cerr << "Adding usage to id=" << ref_id.id << " usr=" << ref_usr
|
// std::cerr << "Adding usage to id=" << ref_id.id << " usr=" << ref_usr
|
||||||
// << " at " << loc.ToString() << std::endl;
|
// << " at " << loc.ToString() << std::endl;
|
||||||
IndexVarId ref_id = db->ToVarId(ref_usr);
|
IndexVarId ref_id = db->ToVarId(ref_usr);
|
||||||
@ -664,9 +628,6 @@ bool AreEqualLocations(CXIdxLoc loc, CXCursor cursor) {
|
|||||||
clang_getRangeStart(clang_Cursor_getSpellingNameRange(cursor, 0, 0)));
|
clang_getRangeStart(clang_Cursor_getSpellingNameRange(cursor, 0, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO TODO TODO TODO
|
|
||||||
// INDEX SPELLING
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -756,7 +717,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
case CXIdxEntity_Field:
|
case CXIdxEntity_Field:
|
||||||
case CXIdxEntity_Variable:
|
case CXIdxEntity_Variable:
|
||||||
case CXIdxEntity_CXXStaticVariable: {
|
case CXIdxEntity_CXXStaticVariable: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
clang::Cursor decl_cursor = decl->cursor;
|
clang::Cursor decl_cursor = decl->cursor;
|
||||||
|
|
||||||
@ -781,11 +742,11 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
if (decl->isDefinition) {
|
if (decl->isDefinition) {
|
||||||
var_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
var_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
var_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor, false /*interesting*/);;
|
var_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var_def->def.declaration = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
var_def->def.declaration = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
}
|
}
|
||||||
UniqueAdd(var_def->uses, decl_loc_spelling);
|
UniqueAdd(var_def->uses, decl_loc_spelling);
|
||||||
|
|
||||||
@ -799,9 +760,9 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// interesting reference for parameter declarations - that is handled when
|
// interesting reference for parameter declarations - that is handled when
|
||||||
// the function declaration is encountered since we won't receive ParmDecl
|
// the function declaration is encountered since we won't receive ParmDecl
|
||||||
// declarations for unnamed parameters.
|
// declarations for unnamed parameters.
|
||||||
|
// TODO: See if we can remove this function call.
|
||||||
AddDeclTypeUsages(
|
AddDeclTypeUsages(
|
||||||
db, decl_cursor,
|
db, decl_cursor,
|
||||||
decl_cursor.get_kind() != CXCursor_ParmDecl /*is_interesting*/,
|
|
||||||
decl->semanticContainer, decl->lexicalContainer);
|
decl->semanticContainer, decl->lexicalContainer);
|
||||||
|
|
||||||
// We don't need to assign declaring type multiple times if this variable
|
// We don't need to assign declaring type multiple times if this variable
|
||||||
@ -836,7 +797,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
case CXIdxEntity_CXXInstanceMethod:
|
case CXIdxEntity_CXXInstanceMethod:
|
||||||
case CXIdxEntity_CXXStaticMethod:
|
case CXIdxEntity_CXXStaticMethod:
|
||||||
case CXIdxEntity_CXXConversionFunction: {
|
case CXIdxEntity_CXXConversionFunction: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
clang::Cursor decl_cursor = decl->cursor;
|
clang::Cursor decl_cursor = decl->cursor;
|
||||||
clang::Cursor resolved =
|
clang::Cursor resolved =
|
||||||
@ -847,20 +808,20 @@ 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.
|
||||||
AddDeclTypeUsages(db, decl_cursor, true /*is_interesting*/,
|
AddDeclTypeUsages(db, decl_cursor,
|
||||||
decl->semanticContainer, decl->lexicalContainer);
|
decl->semanticContainer, decl->lexicalContainer);
|
||||||
|
|
||||||
// TODO: support multiple definitions per function; right now we are
|
// TODO: support multiple definitions per function; right now we are
|
||||||
// hacking the 'declarations' field by
|
// hacking the 'declarations' field by
|
||||||
// adding a definition when we really don't have one.
|
// adding a definition when we really don't have one.
|
||||||
if (decl->isDefinition && !func_def->def.definition_extent.has_value()) {
|
if (decl->isDefinition && !func_def->def.definition_extent.has_value()) {
|
||||||
func_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
func_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
func_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor, false /*interesting*/);
|
func_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);
|
||||||
|
|
||||||
RemoveItem(func_def->declarations, *func_def->def.definition_spelling);
|
RemoveItem(func_def->declarations, *func_def->def.definition_spelling);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Range decl_spelling = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
Range decl_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
// Only add the declaration if it's not already a definition.
|
// Only add the declaration if it's not already a definition.
|
||||||
if (!func_def->def.definition_spelling || *func_def->def.definition_spelling != decl_spelling)
|
if (!func_def->def.definition_spelling || *func_def->def.definition_spelling != decl_spelling)
|
||||||
UniqueAdd(func_def->declarations, decl_spelling);
|
UniqueAdd(func_def->declarations, decl_spelling);
|
||||||
@ -907,7 +868,6 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
func_def->def.declaring_type = declaring_type_id;
|
func_def->def.declaring_type = declaring_type_id;
|
||||||
|
|
||||||
// Mark a type reference at the ctor/dtor location.
|
// Mark a type reference at the ctor/dtor location.
|
||||||
// TODO: Should it be interesting?
|
|
||||||
if (is_ctor_or_dtor) {
|
if (is_ctor_or_dtor) {
|
||||||
Range type_usage_loc = decl_loc_spelling;
|
Range type_usage_loc = decl_loc_spelling;
|
||||||
UniqueAdd(declaring_type_def->uses, type_usage_loc);
|
UniqueAdd(declaring_type_def->uses, type_usage_loc);
|
||||||
@ -919,12 +879,6 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
declaring_type_def->def.funcs.push_back(func_id);
|
declaring_type_def->def.funcs.push_back(func_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeResolution ret_type = ResolveToType(db,
|
|
||||||
// decl_cursor.get_type().get_return_type());
|
|
||||||
// if (ret_type.resolved_type)
|
|
||||||
// AddInterestingUsageToType(db, ret_type,
|
|
||||||
// FindLocationOfTypeSpecifier(decl_cursor));
|
|
||||||
|
|
||||||
if (decl->isDefinition || is_pure_virtual) {
|
if (decl->isDefinition || is_pure_virtual) {
|
||||||
// Mark type usage for parameters as interesting. We handle this here
|
// Mark type usage for parameters as interesting. We handle this here
|
||||||
// instead of inside var declaration because clang will not emit a var
|
// instead of inside var declaration because clang will not emit a var
|
||||||
@ -948,7 +902,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// twice
|
// twice
|
||||||
// because a parameter is not really part of the lexical
|
// because a parameter is not really part of the lexical
|
||||||
// container.
|
// container.
|
||||||
AddDeclTypeUsages(db, arg, true /*is_interesting*/,
|
AddDeclTypeUsages(db, arg,
|
||||||
decl->semanticContainer,
|
decl->semanticContainer,
|
||||||
decl->semanticContainer);
|
decl->semanticContainer);
|
||||||
|
|
||||||
@ -999,13 +953,13 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
|
|
||||||
case CXIdxEntity_Typedef:
|
case CXIdxEntity_Typedef:
|
||||||
case CXIdxEntity_CXXTypeAlias: {
|
case CXIdxEntity_CXXTypeAlias: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor, true /*interesting*/);
|
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
// Note we want to fetch the first TypeRef. Running
|
// Note we want to fetch the first TypeRef. Running
|
||||||
// ResolveCursorType(decl->cursor) would return
|
// ResolveCursorType(decl->cursor) would return
|
||||||
// the type of the typedef/using, not the type of the referenced type.
|
// the type of the typedef/using, not the type of the referenced type.
|
||||||
optional<IndexTypeId> alias_of =
|
optional<IndexTypeId> alias_of =
|
||||||
AddDeclTypeUsages(db, decl->cursor, true /*is_interesting*/,
|
AddDeclTypeUsages(db, decl->cursor,
|
||||||
decl->semanticContainer, decl->lexicalContainer);
|
decl->semanticContainer, decl->lexicalContainer);
|
||||||
|
|
||||||
IndexTypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
IndexTypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
||||||
@ -1018,8 +972,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
type_def->def.detailed_name =
|
type_def->def.detailed_name =
|
||||||
ns->QualifiedName(decl->semanticContainer, type_def->def.short_name);
|
ns->QualifiedName(decl->semanticContainer, type_def->def.short_name);
|
||||||
|
|
||||||
type_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
type_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
type_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor, false /*interesting*/);
|
type_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);
|
||||||
UniqueAdd(type_def->uses, decl_loc_spelling);
|
UniqueAdd(type_def->uses, decl_loc_spelling);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1028,7 +982,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
case CXIdxEntity_Union:
|
case CXIdxEntity_Union:
|
||||||
case CXIdxEntity_Struct:
|
case CXIdxEntity_Struct:
|
||||||
case CXIdxEntity_CXXClass: {
|
case CXIdxEntity_CXXClass: {
|
||||||
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor, true /*interesting*/);
|
Range decl_loc_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
|
|
||||||
IndexTypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
IndexTypeId type_id = db->ToTypeId(decl->entityInfo->USR);
|
||||||
IndexedTypeDef* type_def = db->Resolve(type_id);
|
IndexedTypeDef* type_def = db->Resolve(type_id);
|
||||||
@ -1055,8 +1009,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
assert(decl->isDefinition);
|
assert(decl->isDefinition);
|
||||||
type_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/);
|
type_def->def.definition_spelling = db->id_cache.ResolveSpelling(decl->cursor);
|
||||||
type_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor, false /*interesting*/);
|
type_def->def.definition_extent = db->id_cache.ResolveExtent(decl->cursor);
|
||||||
UniqueAdd(type_def->uses, decl_loc_spelling);
|
UniqueAdd(type_def->uses, decl_loc_spelling);
|
||||||
|
|
||||||
// type_def->alias_of
|
// type_def->alias_of
|
||||||
@ -1072,7 +1026,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
for (unsigned int i = 0; i < class_info->numBases; ++i) {
|
for (unsigned int i = 0; i < class_info->numBases; ++i) {
|
||||||
const CXIdxBaseClassInfo* base_class = class_info->bases[i];
|
const CXIdxBaseClassInfo* base_class = class_info->bases[i];
|
||||||
|
|
||||||
AddDeclTypeUsages(db, base_class->cursor, true /*is_interesting*/,
|
AddDeclTypeUsages(db, base_class->cursor,
|
||||||
decl->semanticContainer, decl->lexicalContainer);
|
decl->semanticContainer, decl->lexicalContainer);
|
||||||
optional<IndexTypeId> parent_type_id =
|
optional<IndexTypeId> parent_type_id =
|
||||||
ResolveToDeclarationType(db, base_class->cursor);
|
ResolveToDeclarationType(db, base_class->cursor);
|
||||||
@ -1093,7 +1047,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
std::cerr
|
std::cerr
|
||||||
<< "!! Unhandled indexDeclaration: "
|
<< "!! Unhandled indexDeclaration: "
|
||||||
<< clang::Cursor(decl->cursor).ToString() << " at "
|
<< clang::Cursor(decl->cursor).ToString() << " at "
|
||||||
<< db->id_cache.ResolveSpelling(decl->cursor, false /*interesting*/).start.ToString()
|
<< db->id_cache.ResolveSpelling(decl->cursor).start.ToString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cerr << " entityInfo->kind = " << decl->entityInfo->kind
|
std::cerr << " entityInfo->kind = " << decl->entityInfo->kind
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@ -1236,7 +1190,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
case CXIdxEntity_CXXStaticVariable:
|
case CXIdxEntity_CXXStaticVariable:
|
||||||
case CXIdxEntity_Variable:
|
case CXIdxEntity_Variable:
|
||||||
case CXIdxEntity_Field: {
|
case CXIdxEntity_Field: {
|
||||||
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor, false /*interesting*/);
|
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor);
|
||||||
|
|
||||||
clang::Cursor referenced = ref->referencedEntity->cursor;
|
clang::Cursor referenced = ref->referencedEntity->cursor;
|
||||||
referenced = referenced.template_specialization_to_template_definition();
|
referenced = referenced.template_specialization_to_template_definition();
|
||||||
@ -1263,7 +1217,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// TODO: search full history?
|
// TODO: search full history?
|
||||||
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor, false /*interesting*/);
|
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor);
|
||||||
|
|
||||||
// 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);
|
||||||
@ -1279,32 +1233,6 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
AddFuncRef(&called_def->callers, IndexFuncRef(loc_spelling));
|
AddFuncRef(&called_def->callers, IndexFuncRef(loc_spelling));
|
||||||
}
|
}
|
||||||
|
|
||||||
// For constructor/destructor, also add a usage against the type. Clang
|
|
||||||
// will insert and visit implicit constructor references, so we also check
|
|
||||||
// the location of the ctor call compared to the parent call. If they are
|
|
||||||
// the same, this is most likely an implicit ctors.
|
|
||||||
clang::Cursor ref_cursor = ref->cursor;
|
|
||||||
if (ref->referencedEntity->kind == CXIdxEntity_CXXConstructor ||
|
|
||||||
ref->referencedEntity->kind == CXIdxEntity_CXXDestructor) {
|
|
||||||
|
|
||||||
|
|
||||||
//CXFile file;
|
|
||||||
//unsigned int line, column, offset;
|
|
||||||
//clang_getSpellingLocation(clang_indexLoc_getCXSourceLocation(ref->loc), &file, &line, &column, &offset);
|
|
||||||
|
|
||||||
Range parent_loc = db->id_cache.ResolveSpelling(ref->parentEntity->cursor, true /*interesting*/);
|
|
||||||
if (parent_loc.start != loc_spelling.start) {
|
|
||||||
IndexedFuncDef* called_def = db->Resolve(called_id);
|
|
||||||
// I suspect it is possible for the declaring type to be null
|
|
||||||
// when the class is invalid.
|
|
||||||
if (called_def->def.declaring_type) {
|
|
||||||
// assert(called_def->def.declaring_type.has_value());
|
|
||||||
IndexedTypeDef* type_def =
|
|
||||||
db->Resolve(called_def->def.declaring_type.value());
|
|
||||||
UniqueAdd(type_def->uses, loc_spelling.WithInteresting(true), false /*insert_if_not_present*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1314,7 +1242,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
case CXIdxEntity_Union:
|
case CXIdxEntity_Union:
|
||||||
case CXIdxEntity_Struct:
|
case CXIdxEntity_Struct:
|
||||||
case CXIdxEntity_CXXClass: {
|
case CXIdxEntity_CXXClass: {
|
||||||
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor, false /*interesting*/);
|
Range loc_spelling = db->id_cache.ResolveSpelling(ref->cursor);
|
||||||
|
|
||||||
clang::Cursor referenced = ref->referencedEntity->cursor;
|
clang::Cursor referenced = ref->referencedEntity->cursor;
|
||||||
referenced = referenced.template_specialization_to_template_definition();
|
referenced = referenced.template_specialization_to_template_definition();
|
||||||
@ -1346,7 +1274,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
std::cerr
|
std::cerr
|
||||||
<< "!! Unhandled indexEntityReference: " << cursor.ToString()
|
<< "!! Unhandled indexEntityReference: " << cursor.ToString()
|
||||||
<< " at "
|
<< " at "
|
||||||
<< db->id_cache.ResolveSpelling(ref->cursor, false /*interesting*/).start.ToString()
|
<< db->id_cache.ResolveSpelling(ref->cursor).start.ToString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cerr << " ref->referencedEntity->kind = "
|
std::cerr << " ref->referencedEntity->kind = "
|
||||||
<< ref->referencedEntity->kind << std::endl;
|
<< ref->referencedEntity->kind << std::endl;
|
||||||
@ -1355,7 +1283,7 @@ void indexEntityReference(CXClientData client_data,
|
|||||||
<< ref->parentEntity->kind << std::endl;
|
<< ref->parentEntity->kind << std::endl;
|
||||||
std::cerr
|
std::cerr
|
||||||
<< " ref->loc = "
|
<< " ref->loc = "
|
||||||
<< db->id_cache.ResolveSpelling(ref->cursor, false /*interesting*/).start.ToString()
|
<< db->id_cache.ResolveSpelling(ref->cursor).start.ToString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cerr << " ref->kind = " << ref->kind << std::endl;
|
std::cerr << " ref->kind = " << ref->kind << std::endl;
|
||||||
if (ref->parentEntity)
|
if (ref->parentEntity)
|
||||||
|
@ -425,9 +425,9 @@ struct IdCache {
|
|||||||
|
|
||||||
IdCache(const std::string& primary_file);
|
IdCache(const std::string& primary_file);
|
||||||
|
|
||||||
Range Resolve(const CXSourceRange& range, bool interesting);
|
Range Resolve(const CXSourceRange& range);
|
||||||
Range ResolveSpelling(const CXCursor& cx_cursor, bool interesting);
|
Range ResolveSpelling(const CXCursor& cx_cursor);
|
||||||
Range ResolveExtent(const CXCursor& cx_cursor, bool interesting);
|
Range ResolveExtent(const CXCursor& cx_cursor);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexedFile {
|
struct IndexedFile {
|
||||||
|
@ -69,7 +69,7 @@ bool Position::operator<(const Position& that) const {
|
|||||||
|
|
||||||
Range::Range() {}
|
Range::Range() {}
|
||||||
|
|
||||||
Range::Range(bool interesting, Position start, Position end) : interesting(interesting), start(start), end(end) {}
|
Range::Range(Position start, Position end) : start(start), end(end) {}
|
||||||
|
|
||||||
Range::Range(const char* encoded) {
|
Range::Range(const char* encoded) {
|
||||||
end = start;
|
end = start;
|
||||||
@ -125,12 +125,6 @@ std::string Range::ToString() {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
Range Range::WithInteresting(bool interesting) {
|
|
||||||
Range result = *this;
|
|
||||||
result.interesting = interesting;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Range::operator==(const Range& that) const {
|
bool Range::operator==(const Range& that) const {
|
||||||
return start == that.start && end == that.end;
|
return start == that.start && end == that.end;
|
||||||
}
|
}
|
||||||
|
@ -23,18 +23,16 @@ struct Position {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Range {
|
struct Range {
|
||||||
bool interesting = false;
|
|
||||||
Position start;
|
Position start;
|
||||||
Position end;
|
Position end;
|
||||||
|
|
||||||
Range();
|
Range();
|
||||||
Range(bool interesting, Position start, Position end);
|
Range(Position start, Position end);
|
||||||
explicit Range(const char* encoded);
|
explicit Range(const char* encoded);
|
||||||
|
|
||||||
bool Contains(int line, int column) const;
|
bool Contains(int line, int column) const;
|
||||||
|
|
||||||
std::string ToString();
|
std::string ToString();
|
||||||
Range WithInteresting(bool interesting);
|
|
||||||
|
|
||||||
bool operator==(const Range& that) const;
|
bool operator==(const Range& that) const;
|
||||||
bool operator!=(const Range& that) const;
|
bool operator!=(const Range& that) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user