mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 23:55:08 +00:00
parent
1349cbfde3
commit
217d238c78
@ -21,6 +21,10 @@
|
|||||||
// Defined in command_line.cc
|
// Defined in command_line.cc
|
||||||
extern bool g_debug;
|
extern bool g_debug;
|
||||||
|
|
||||||
|
#if CINDEX_VERSION >= 47
|
||||||
|
#define CINDEX_HAVE_PRETTY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr bool kIndexStdDeclarations = true;
|
constexpr bool kIndexStdDeclarations = true;
|
||||||
@ -259,6 +263,30 @@ struct IndexParam {
|
|||||||
|
|
||||||
IndexParam(Config* config, ClangTranslationUnit* tu, FileConsumer* file_consumer)
|
IndexParam(Config* config, ClangTranslationUnit* tu, FileConsumer* file_consumer)
|
||||||
: config(config), tu(tu), file_consumer(file_consumer) {}
|
: config(config), tu(tu), file_consumer(file_consumer) {}
|
||||||
|
|
||||||
|
#if CINDEX_HAVE_PRETTY
|
||||||
|
CXPrintingPolicy print_policy = nullptr;
|
||||||
|
CXPrintingPolicy print_policy_more = nullptr;
|
||||||
|
~IndexParam() {
|
||||||
|
clang_PrintingPolicy_dispose(print_policy);
|
||||||
|
clang_PrintingPolicy_dispose(print_policy_more);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PrettyPrintCursor(CXCursor cursor, bool initializer = true) {
|
||||||
|
if (!print_policy) {
|
||||||
|
print_policy = clang_getCursorPrintingPolicy(cursor);
|
||||||
|
clang_PrintingPolicy_setProperty(print_policy,
|
||||||
|
CXPrintingPolicy_TerseOutput, 1);
|
||||||
|
clang_PrintingPolicy_setProperty(print_policy,
|
||||||
|
CXPrintingPolicy_SuppressInitializers, 1);
|
||||||
|
print_policy_more = clang_getCursorPrintingPolicy(cursor);
|
||||||
|
clang_PrintingPolicy_setProperty(print_policy_more,
|
||||||
|
CXPrintingPolicy_TerseOutput, 1);
|
||||||
|
}
|
||||||
|
return ToString(clang_getCursorPrettyPrinted(
|
||||||
|
cursor, initializer ? print_policy_more : print_policy));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
IndexFile* ConsumeFile(IndexParam* param, CXFile file) {
|
IndexFile* ConsumeFile(IndexParam* param, CXFile file) {
|
||||||
@ -409,7 +437,7 @@ void SetTypeName(IndexType* type,
|
|||||||
const ClangCursor& cursor,
|
const ClangCursor& cursor,
|
||||||
const CXIdxContainerInfo* container,
|
const CXIdxContainerInfo* container,
|
||||||
const char* name,
|
const char* name,
|
||||||
NamespaceHelper* ns) {
|
IndexParam* param) {
|
||||||
CXIdxContainerInfo parent;
|
CXIdxContainerInfo parent;
|
||||||
// |name| can be null in an anonymous struct (see
|
// |name| can be null in an anonymous struct (see
|
||||||
// tests/types/anonymous_struct.cc).
|
// tests/types/anonymous_struct.cc).
|
||||||
@ -417,8 +445,9 @@ void SetTypeName(IndexType* type,
|
|||||||
name = "(anon)";
|
name = "(anon)";
|
||||||
if (!container)
|
if (!container)
|
||||||
parent.cursor = cursor.get_semantic_parent().cx_cursor;
|
parent.cursor = cursor.get_semantic_parent().cx_cursor;
|
||||||
|
// Investigate why clang_getCursorPrettyPrinted is not fully qualified.
|
||||||
type->def.detailed_name =
|
type->def.detailed_name =
|
||||||
ns->QualifiedName(container ? container : &parent, name);
|
param->ns.QualifiedName(container ? container : &parent, name);
|
||||||
auto idx = type->def.detailed_name.find(name);
|
auto idx = type->def.detailed_name.find(name);
|
||||||
assert(idx != std::string::npos);
|
assert(idx != std::string::npos);
|
||||||
type->def.short_name_offset = idx;
|
type->def.short_name_offset = idx;
|
||||||
@ -431,7 +460,7 @@ void SetTypeName(IndexType* type,
|
|||||||
// (ie, Foo<A,B> => Foo<*,*>).
|
// (ie, Foo<A,B> => Foo<*,*>).
|
||||||
optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
||||||
ClangCursor cursor,
|
ClangCursor cursor,
|
||||||
NamespaceHelper* ns) {
|
IndexParam* param) {
|
||||||
ClangType type = cursor.get_type();
|
ClangType type = cursor.get_type();
|
||||||
|
|
||||||
// auto x = new Foo() will not be deduced to |Foo| if we do not use the
|
// auto x = new Foo() will not be deduced to |Foo| if we do not use the
|
||||||
@ -461,7 +490,7 @@ optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
|||||||
IndexType* typ = db->Resolve(type_id);
|
IndexType* typ = db->Resolve(type_id);
|
||||||
if (typ->def.detailed_name.empty()) {
|
if (typ->def.detailed_name.empty()) {
|
||||||
std::string name = declaration.get_spelling();
|
std::string name = declaration.get_spelling();
|
||||||
SetTypeName(typ, declaration, nullptr, name.c_str(), ns);
|
SetTypeName(typ, declaration, nullptr, name.c_str(), param);
|
||||||
}
|
}
|
||||||
return type_id;
|
return type_id;
|
||||||
}
|
}
|
||||||
@ -484,7 +513,12 @@ void SetVarDetail(IndexVar* var,
|
|||||||
def.storage = GetStorageClass(clang_Cursor_getStorageClass(cursor.cx_cursor));
|
def.storage = GetStorageClass(clang_Cursor_getStorageClass(cursor.cx_cursor));
|
||||||
|
|
||||||
std::string qualified_name =
|
std::string qualified_name =
|
||||||
param->ns.QualifiedName(semanticContainer, short_name);
|
#if CINDEX_HAVE_PRETTY
|
||||||
|
cursor.get_kind() != CXCursor_EnumConstantDecl
|
||||||
|
? param->PrettyPrintCursor(cursor.cx_cursor)
|
||||||
|
:
|
||||||
|
#endif
|
||||||
|
param->ns.QualifiedName(semanticContainer, short_name);
|
||||||
|
|
||||||
if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) {
|
if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) {
|
||||||
CXType enum_type = clang_getCanonicalType(
|
CXType enum_type = clang_getCanonicalType(
|
||||||
@ -499,6 +533,10 @@ void SetVarDetail(IndexVar* var,
|
|||||||
def.detailed_name = std::move(qualified_name);
|
def.detailed_name = std::move(qualified_name);
|
||||||
def.hover = hover;
|
def.hover = hover;
|
||||||
} else {
|
} else {
|
||||||
|
#if CINDEX_HAVE_PRETTY
|
||||||
|
def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor, false);
|
||||||
|
def.hover = std::move(qualified_name);
|
||||||
|
#else
|
||||||
def.detailed_name = std::move(type_name);
|
def.detailed_name = std::move(type_name);
|
||||||
ConcatTypeAndName(def.detailed_name, qualified_name);
|
ConcatTypeAndName(def.detailed_name, qualified_name);
|
||||||
// Append the textual initializer, bit field, constructor to |hover|.
|
// Append the textual initializer, bit field, constructor to |hover|.
|
||||||
@ -521,6 +559,7 @@ void SetVarDetail(IndexVar* var,
|
|||||||
def.hover = def.detailed_name +
|
def.hover = def.detailed_name +
|
||||||
fc.content.substr(*spell_end, *extent_end - *spell_end);
|
fc.content.substr(*spell_end, *extent_end - *spell_end);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// FIXME QualifiedName should return index
|
// FIXME QualifiedName should return index
|
||||||
auto idx = def.detailed_name.find(short_name.begin(), 0, short_name.size());
|
auto idx = def.detailed_name.find(short_name.begin(), 0, short_name.size());
|
||||||
@ -530,7 +569,7 @@ void SetVarDetail(IndexVar* var,
|
|||||||
|
|
||||||
if (is_first_seen) {
|
if (is_first_seen) {
|
||||||
optional<IndexTypeId> var_type =
|
optional<IndexTypeId> var_type =
|
||||||
ResolveToDeclarationType(db, cursor, ¶m->ns);
|
ResolveToDeclarationType(db, cursor, param);
|
||||||
if (var_type) {
|
if (var_type) {
|
||||||
// Don't treat enum definition variables as instantiations.
|
// Don't treat enum definition variables as instantiations.
|
||||||
bool is_enum_member = semanticContainer &&
|
bool is_enum_member = semanticContainer &&
|
||||||
@ -1186,6 +1225,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
|||||||
ClangCursor parent,
|
ClangCursor parent,
|
||||||
TemplateVisitorData* data) {
|
TemplateVisitorData* data) {
|
||||||
IndexFile* db = data->db;
|
IndexFile* db = data->db;
|
||||||
|
IndexParam* param = data->param;
|
||||||
switch (cursor.get_kind()) {
|
switch (cursor.get_kind()) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1199,7 +1239,7 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
|||||||
ref_index->def.definition_extent = ref_cursor.get_extent();
|
ref_index->def.definition_extent = ref_cursor.get_extent();
|
||||||
ref_index->def.kind = ClangSymbolKind::Parameter;
|
ref_index->def.kind = ClangSymbolKind::Parameter;
|
||||||
SetVarDetail(ref_index, ref_cursor.get_spelling(), ref_cursor,
|
SetVarDetail(ref_index, ref_cursor.get_spelling(), ref_cursor,
|
||||||
nullptr, true, db, data->param);
|
nullptr, true, db, param);
|
||||||
|
|
||||||
ClangType ref_type = clang_getCursorType(ref_cursor.cx_cursor);
|
ClangType ref_type = clang_getCursorType(ref_cursor.cx_cursor);
|
||||||
// TODO optimize
|
// TODO optimize
|
||||||
@ -1250,7 +1290,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
|||||||
if (ref_index->def.detailed_name.empty()) {
|
if (ref_index->def.detailed_name.empty()) {
|
||||||
ref_index->def.definition_spelling = ref_cursor.get_spelling_range();
|
ref_index->def.definition_spelling = ref_cursor.get_spelling_range();
|
||||||
ref_index->def.definition_extent = ref_cursor.get_extent();
|
ref_index->def.definition_extent = ref_cursor.get_extent();
|
||||||
|
#if CINDEX_HAVE_PRETTY
|
||||||
|
ref_index->def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor);
|
||||||
|
#else
|
||||||
ref_index->def.detailed_name = ref_cursor.get_spelling();
|
ref_index->def.detailed_name = ref_cursor.get_spelling();
|
||||||
|
#endif
|
||||||
ref_index->def.short_name_offset = 0;
|
ref_index->def.short_name_offset = 0;
|
||||||
ref_index->def.short_name_size = ref_index->def.detailed_name.size();
|
ref_index->def.short_name_size = ref_index->def.detailed_name.size();
|
||||||
ref_index->def.kind = ClangSymbolKind::Parameter;
|
ref_index->def.kind = ClangSymbolKind::Parameter;
|
||||||
@ -1272,7 +1316,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
|||||||
if (ref_index->def.detailed_name.empty()) {
|
if (ref_index->def.detailed_name.empty()) {
|
||||||
ref_index->def.definition_spelling = ref_cursor.get_spelling_range();
|
ref_index->def.definition_spelling = ref_cursor.get_spelling_range();
|
||||||
ref_index->def.definition_extent = ref_cursor.get_extent();
|
ref_index->def.definition_extent = ref_cursor.get_extent();
|
||||||
|
#if CINDEX_HAVE_PRETTY
|
||||||
|
ref_index->def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor);
|
||||||
|
#else
|
||||||
ref_index->def.detailed_name = ref_cursor.get_spelling();
|
ref_index->def.detailed_name = ref_cursor.get_spelling();
|
||||||
|
#endif
|
||||||
ref_index->def.short_name_offset = 0;
|
ref_index->def.short_name_offset = 0;
|
||||||
ref_index->def.short_name_size = ref_index->def.detailed_name.size();
|
ref_index->def.short_name_size = ref_index->def.detailed_name.size();
|
||||||
ref_index->def.kind = ClangSymbolKind::Parameter;
|
ref_index->def.kind = ClangSymbolKind::Parameter;
|
||||||
@ -1391,7 +1439,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
ns->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
ns->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
||||||
if (ns->def.detailed_name.empty()) {
|
if (ns->def.detailed_name.empty()) {
|
||||||
SetTypeName(ns, decl_cursor, decl->semanticContainer,
|
SetTypeName(ns, decl_cursor, decl->semanticContainer,
|
||||||
decl->entityInfo->name, ¶m->ns);
|
decl->entityInfo->name, param);
|
||||||
ns->def.definition_spelling = decl_spell;
|
ns->def.definition_spelling = decl_spell;
|
||||||
ns->def.definition_extent = decl_cursor.get_extent();
|
ns->def.definition_extent = decl_cursor.get_extent();
|
||||||
if (decl->semanticContainer) {
|
if (decl->semanticContainer) {
|
||||||
@ -1557,7 +1605,11 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// Build detailed name. The type desc looks like void (void *). We
|
// Build detailed name. The type desc looks like void (void *). We
|
||||||
// insert the qualified name before the first '('.
|
// insert the qualified name before the first '('.
|
||||||
// FIXME GetFunctionSignature should set index
|
// FIXME GetFunctionSignature should set index
|
||||||
|
#if CINDEX_HAVE_PRETTY
|
||||||
|
func->def.detailed_name = param->PrettyPrintCursor(decl->cursor);
|
||||||
|
#else
|
||||||
func->def.detailed_name = GetFunctionSignature(db, ns, decl);
|
func->def.detailed_name = GetFunctionSignature(db, ns, decl);
|
||||||
|
#endif
|
||||||
auto idx = func->def.detailed_name.find(decl->entityInfo->name);
|
auto idx = func->def.detailed_name.find(decl->entityInfo->name);
|
||||||
assert(idx != std::string::npos);
|
assert(idx != std::string::npos);
|
||||||
func->def.short_name_offset = idx;
|
func->def.short_name_offset = idx;
|
||||||
@ -1645,7 +1697,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
type->def.definition_extent = extent;
|
type->def.definition_extent = extent;
|
||||||
|
|
||||||
SetTypeName(type, decl_cursor, decl->semanticContainer,
|
SetTypeName(type, decl_cursor, decl->semanticContainer,
|
||||||
decl->entityInfo->name, ¶m->ns);
|
decl->entityInfo->name, param);
|
||||||
type->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
type->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
||||||
type->def.comments = decl_cursor.get_comments();
|
type->def.comments = decl_cursor.get_comments();
|
||||||
|
|
||||||
@ -1691,7 +1743,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// if (!decl->isRedeclaration) {
|
// if (!decl->isRedeclaration) {
|
||||||
|
|
||||||
SetTypeName(type, decl_cursor, decl->semanticContainer,
|
SetTypeName(type, decl_cursor, decl->semanticContainer,
|
||||||
decl->entityInfo->name, ¶m->ns);
|
decl->entityInfo->name, param);
|
||||||
type->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
type->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
||||||
type->def.comments = decl_cursor.get_comments();
|
type->def.comments = decl_cursor.get_comments();
|
||||||
// }
|
// }
|
||||||
@ -1730,7 +1782,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
// cursor
|
// cursor
|
||||||
if (origin->def.detailed_name.empty()) {
|
if (origin->def.detailed_name.empty()) {
|
||||||
SetTypeName(origin, origin_cursor, nullptr,
|
SetTypeName(origin, origin_cursor, nullptr,
|
||||||
&type->def.ShortName()[0], ns);
|
&type->def.ShortName()[0], param);
|
||||||
origin->def.kind = type->def.kind;
|
origin->def.kind = type->def.kind;
|
||||||
}
|
}
|
||||||
// TODO The name may be assigned in |ResolveToDeclarationType| but
|
// TODO The name may be assigned in |ResolveToDeclarationType| but
|
||||||
@ -1770,7 +1822,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
|||||||
AddDeclTypeUsages(db, base_class->cursor, nullopt,
|
AddDeclTypeUsages(db, base_class->cursor, nullopt,
|
||||||
decl->semanticContainer, decl->lexicalContainer);
|
decl->semanticContainer, decl->lexicalContainer);
|
||||||
optional<IndexTypeId> parent_type_id =
|
optional<IndexTypeId> parent_type_id =
|
||||||
ResolveToDeclarationType(db, base_class->cursor, ¶m->ns);
|
ResolveToDeclarationType(db, base_class->cursor, param);
|
||||||
// type_def ptr could be invalidated by ResolveToDeclarationType and
|
// type_def ptr could be invalidated by ResolveToDeclarationType and
|
||||||
// TemplateVisitor.
|
// TemplateVisitor.
|
||||||
type = db->Resolve(type_id);
|
type = db->Resolve(type_id);
|
||||||
|
Loading…
Reference in New Issue
Block a user