Use clang_getCursorPrettyPrinted if CINDEX_VERSION >= 47

Closes #366
This commit is contained in:
Fangrui Song 2018-02-04 14:54:08 -08:00
parent 1349cbfde3
commit 217d238c78

View File

@ -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,6 +513,11 @@ 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 =
#if CINDEX_HAVE_PRETTY
cursor.get_kind() != CXCursor_EnumConstantDecl
? param->PrettyPrintCursor(cursor.cx_cursor)
:
#endif
param->ns.QualifiedName(semanticContainer, short_name); param->ns.QualifiedName(semanticContainer, short_name);
if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) { if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) {
@ -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, &param->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, &param->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, &param->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, &param->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, &param->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);