More cleanup in indexer

This commit is contained in:
Jacob Dufault 2017-05-27 12:56:39 -07:00
parent e431dbd793
commit dcc71f2470

View File

@ -301,9 +301,10 @@ void RemoveItem(std::vector<Range>& ranges, Range to_remove) {
ranges.erase(it); ranges.erase(it);
} }
void UniqueAdd(std::vector<Range>& uses, Range loc) { template <typename T>
if (std::find(uses.begin(), uses.end(), loc) == uses.end()) void UniqueAdd(std::vector<T>& values, T value) {
uses.push_back(loc); if (std::find(values.begin(), values.end(), value) == values.end())
values.push_back(value);
} }
IdCache::IdCache(const std::string& primary_file) IdCache::IdCache(const std::string& primary_file)
@ -984,10 +985,10 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
Range decl_loc_spelling = ResolveSpelling(decl->cursor); Range decl_loc_spelling = ResolveSpelling(decl->cursor);
clang::Cursor decl_cursor = decl->cursor; clang::Cursor decl_cursor = decl->cursor;
clang::Cursor resolved = clang::Cursor decl_cursor_resolved = decl_cursor.template_specialization_to_template_definition();
decl_cursor.template_specialization_to_template_definition(); bool is_template_specialization = decl_cursor != decl_cursor_resolved;
IndexFuncId func_id = db->ToFuncId(resolved.cx_cursor); IndexFuncId func_id = db->ToFuncId(decl_cursor_resolved.cx_cursor);
IndexFunc* func = db->Resolve(func_id); IndexFunc* func = db->Resolve(func_id);
// 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
@ -995,42 +996,27 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
AddDeclTypeUsages(db, decl_cursor, AddDeclTypeUsages(db, decl_cursor,
decl->semanticContainer, decl->lexicalContainer); decl->semanticContainer, decl->lexicalContainer);
// Add definition or declaration. This is a bit tricky because we treat
// We always need to build the short/qualified name for the function, // template specializations as declarations, even though they are
// because we may be parsing a declaration with no definition (ie, pure // technically definitions.
// virtual, class header but no impl yet, etc). // TODO: Support multiple function definitions, which is common for
// If decl_cursor != resolved, then decl_cursor is a template // template specializations.
// specialization. We don't want to override a lot of the function if (decl->isDefinition && !is_template_specialization) {
// definition information in that scenario. assert(!func->def.definition_spelling);
//bool is_pure_virtual = clang_CXXMethod_isPureVirtual(decl->cursor); assert(!func->def.definition_extent);
// if (decl->isDefinition && decl_cursor == resolved) {
// func_def->def.definition_spelling = ResolveSpelling(decl->cursor);
// func_def->def.definition_extent = ResolveExtent(decl->cursor);
// 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.definition_extent.has_value()) {
func->def.definition_spelling = ResolveSpelling(decl->cursor); func->def.definition_spelling = ResolveSpelling(decl->cursor);
func->def.definition_extent = ResolveExtent(decl->cursor); func->def.definition_extent = ResolveExtent(decl->cursor);
RemoveItem(func->declarations, *func->def.definition_spelling);
} }
else { else {
Range decl_spelling = ResolveSpelling(decl->cursor); func->declarations.push_back(ResolveSpelling(decl->cursor));
// Only add the declaration if it's not already a definition.
if (!func->def.definition_spelling || *func->def.definition_spelling != decl_spelling)
UniqueAdd(func->declarations, decl_spelling);
} }
// If decl_cursor != resolved, then decl_cursor is a template // Emit definition data for the function. We do this even if it isn't a
// specialization. We don't want to override a lot of the function // definition because there can be, for example, interfaces, or a class
// definition information in that scenario. // declaration that doesn't have a definition yet. If we never end up
if (decl_cursor == resolved) { // indexing the definition, then there will not be any (ie) outline
// TODO: Eventually run with this if. Right now I want to iron out bugs // information.
// this may shadow. if (!is_template_specialization) {
// if (!decl->isRedeclaration) {
func->def.short_name = decl->entityInfo->name; func->def.short_name = decl->entityInfo->name;
// Build detailed name. The type desc looks like void (void *). We // Build detailed name. The type desc looks like void (void *). We
@ -1041,11 +1027,6 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
type_desc.insert(offset, qualified_name); type_desc.insert(offset, qualified_name);
func->def.detailed_name = type_desc; func->def.detailed_name = type_desc;
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;
// Add function usage information. We only want to do it once per // Add function usage information. We only want to do it once per
// definition/declaration. Do it on definition since there should only // definition/declaration. Do it on definition since there should only
// ever be one of those in the entire program. // ever be one of those in the entire program.
@ -1056,15 +1037,14 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
func->def.declaring_type = declaring_type_id; func->def.declaring_type = declaring_type_id;
// Mark a type reference at the ctor/dtor location. // Mark a type reference at the ctor/dtor location.
if (is_ctor_or_dtor) { if (decl->entityInfo->kind == CXIdxEntity_CXXConstructor)
Range type_usage_loc = decl_loc_spelling; UniqueAdd(declaring_type_def->uses, decl_loc_spelling);
UniqueAdd(declaring_type_def->uses, type_usage_loc); // TODO/FIXME: +1 on dtor start range.
} if (decl->entityInfo->kind == CXIdxEntity_CXXDestructor)
UniqueAdd(declaring_type_def->uses, decl_loc_spelling);
// Register function in declaring type if it hasn't been registered // Add function to declaring type.
// yet. UniqueAdd(declaring_type_def->def.funcs, func_id);
if (!Contains(declaring_type_def->def.funcs, func_id))
declaring_type_def->def.funcs.push_back(func_id);
} }
// Process inheritance. // Process inheritance.