mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-22 08:29:38 +00:00
better specialized function definition indexing
This commit is contained in:
parent
f6967eee48
commit
f7e2b20059
42
indexer.cpp
42
indexer.cpp
@ -540,15 +540,16 @@ optional<TypeId> AddDeclUsages(IndexedFile* db, clang::Cursor decl_cursor,
|
|||||||
VisitDeclForTypeUsageVisitorHandler(param.previous_cursor.value(), ¶m);
|
VisitDeclForTypeUsageVisitorHandler(param.previous_cursor.value(), ¶m);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If we are not processing the last type ref, it *must* be a TypeRef (ie,
|
// If we are not processing the last type ref, it *must* be a TypeRef or
|
||||||
// and not a TemplateRef).
|
// TemplateRef.
|
||||||
//
|
//
|
||||||
// We will not visit every child if the is_interseting is false, so previous_cursor
|
// We will not visit every child if the is_interseting is false, so previous_cursor
|
||||||
// may not point to the last TemplateRef.
|
// may not point to the last TemplateRef.
|
||||||
assert(
|
assert(
|
||||||
is_interesting == false ||
|
is_interesting == false ||
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
return param.initial_type;
|
return param.initial_type;
|
||||||
@ -632,9 +633,29 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
case CXIdxEntity_CXXConversionFunction:
|
case CXIdxEntity_CXXConversionFunction:
|
||||||
{
|
{
|
||||||
clang::Cursor decl_cursor = decl->cursor;
|
clang::Cursor decl_cursor = decl->cursor;
|
||||||
FuncId func_id = db->ToFuncId(decl->entityInfo->USR);
|
clang::Cursor resolved = decl_cursor.template_specialization_to_template_definition();
|
||||||
|
|
||||||
|
FuncId func_id = db->ToFuncId(resolved.cx_cursor);
|
||||||
IndexedFuncDef* func_def = db->Resolve(func_id);
|
IndexedFuncDef* func_def = db->Resolve(func_id);
|
||||||
|
|
||||||
|
Location decl_loc = db->id_cache.Resolve(decl->loc, false /*interesting*/);
|
||||||
|
|
||||||
|
func_def->uses.push_back(decl_loc);
|
||||||
|
// We don't actually need to know the return type, but we need to mark it
|
||||||
|
// as an interesting usage.
|
||||||
|
AddDeclUsages(db, decl_cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
||||||
|
|
||||||
|
// TODO: support multiple definitions per function; right now we are hacking the 'declarations' field by
|
||||||
|
// adding a definition when we really don't have one.
|
||||||
|
if (decl->isDefinition && !func_def->def.definition.has_value())
|
||||||
|
func_def->def.definition = decl_loc;
|
||||||
|
else
|
||||||
|
func_def->declarations.push_back(decl_loc);
|
||||||
|
|
||||||
|
// If decl_cursor != resolved, then decl_cursor is a template specialization. We
|
||||||
|
// don't want to override a lot of the function definition information in that
|
||||||
|
// scenario.
|
||||||
|
if (decl_cursor == resolved) {
|
||||||
func_def->is_bad_def = is_system_def;
|
func_def->is_bad_def = is_system_def;
|
||||||
|
|
||||||
// TODO: Eventually run with this if. Right now I want to iron out bugs this may shadow.
|
// TODO: Eventually run with this if. Right now I want to iron out bugs this may shadow.
|
||||||
@ -643,13 +664,6 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
func_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, func_def->def.short_name);
|
func_def->def.qualified_name = ns->QualifiedName(decl->semanticContainer, func_def->def.short_name);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
Location decl_loc = db->id_cache.Resolve(decl->loc, false /*interesting*/);
|
|
||||||
if (decl->isDefinition)
|
|
||||||
func_def->def.definition = decl_loc;
|
|
||||||
else
|
|
||||||
func_def->declarations.push_back(decl_loc);
|
|
||||||
func_def->uses.push_back(decl_loc);
|
|
||||||
|
|
||||||
bool is_pure_virtual = clang_CXXMethod_isPureVirtual(decl->cursor);
|
bool is_pure_virtual = clang_CXXMethod_isPureVirtual(decl->cursor);
|
||||||
bool is_ctor_or_dtor = decl->entityInfo->kind == CXIdxEntity_CXXConstructor || decl->entityInfo->kind == CXIdxEntity_CXXDestructor;
|
bool is_ctor_or_dtor = decl->entityInfo->kind == CXIdxEntity_CXXConstructor || decl->entityInfo->kind == CXIdxEntity_CXXDestructor;
|
||||||
//bool process_declaring_type = is_pure_virtual || is_ctor_or_dtor;
|
//bool process_declaring_type = is_pure_virtual || is_ctor_or_dtor;
|
||||||
@ -675,11 +689,6 @@ 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.
|
|
||||||
AddDeclUsages(db, decl_cursor, true /*is_interesting*/, decl->semanticContainer, decl->lexicalContainer);
|
|
||||||
|
|
||||||
//TypeResolution ret_type = ResolveToType(db, decl_cursor.get_type().get_return_type());
|
//TypeResolution ret_type = ResolveToType(db, decl_cursor.get_type().get_return_type());
|
||||||
//if (ret_type.resolved_type)
|
//if (ret_type.resolved_type)
|
||||||
// AddInterestingUsageToType(db, ret_type, FindLocationOfTypeSpecifier(decl_cursor));
|
// AddInterestingUsageToType(db, ret_type, FindLocationOfTypeSpecifier(decl_cursor));
|
||||||
@ -733,6 +742,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
clang_disposeOverriddenCursors(overridden);
|
clang_disposeOverriddenCursors(overridden);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
optional<FuncId> base;
|
optional<FuncId> base;
|
||||||
|
3
test.cc
3
test.cc
@ -94,9 +94,10 @@ int main(int argc, char** argv) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
for (std::string path : GetFilesInFolder("tests", true /*add_folder_to_path*/)) {
|
for (std::string path : GetFilesInFolder("tests", true /*add_folder_to_path*/)) {
|
||||||
//if (path != "tests/templates/func_specialized_template_param.cc") continue;
|
//if (path != "tests/templates/specialized_func_definition.cc") continue;
|
||||||
//if (path != "tests/constructors/invalid_reference.cc") continue;
|
//if (path != "tests/constructors/invalid_reference.cc") continue;
|
||||||
//if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
//if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
||||||
|
//if (path != "tests/foobar.cc") continue;
|
||||||
if (path == "tests/stl.cc") continue;
|
if (path == "tests/stl.cc") continue;
|
||||||
|
|
||||||
//if (path != "tests/templates/template_class_type_usage_folded_into_one.cc") continue;
|
//if (path != "tests/templates/template_class_type_usage_folded_into_one.cc") continue;
|
||||||
|
39
tests/templates/specialized_func_definition.cc
Normal file
39
tests/templates/specialized_func_definition.cc
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
template<class T>
|
||||||
|
class Template {
|
||||||
|
void Foo();
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void Template<T>::Foo() {}
|
||||||
|
|
||||||
|
void Template<void>::Foo() {}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: usage information on Template is bad.
|
||||||
|
// TODO: Foo() should have multiple definitions.
|
||||||
|
|
||||||
|
OUTPUT:
|
||||||
|
{
|
||||||
|
"types": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:@ST>1#T@Template",
|
||||||
|
"short_name": "Template",
|
||||||
|
"qualified_name": "Template",
|
||||||
|
"definition": "1:2:7",
|
||||||
|
"funcs": [0],
|
||||||
|
"uses": ["*1:2:7", "*1:7:6", "1:9:6"]
|
||||||
|
}],
|
||||||
|
"functions": [{
|
||||||
|
"id": 0,
|
||||||
|
"usr": "c:@ST>1#T@Template@F@Foo#",
|
||||||
|
"short_name": "Foo",
|
||||||
|
"qualified_name": "Template::Foo",
|
||||||
|
"declarations": ["1:3:8", "1:9:22"],
|
||||||
|
"definition": "1:7:19",
|
||||||
|
"declaring_type": 0,
|
||||||
|
"uses": ["1:3:8", "1:7:19", "1:9:22"]
|
||||||
|
}],
|
||||||
|
"variables": []
|
||||||
|
}
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user