$ccls/memberHierarchy: add field offset

This commit is contained in:
Fangrui Song 2018-05-28 17:03:14 -07:00
parent a962061698
commit 42bcf2b58f
26 changed files with 173 additions and 60 deletions

View File

@ -37,7 +37,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [9736582033442720743], "vars": [{
"L": 9736582033442720743,
"R": 0
}],
"instances": [], "instances": [],
"uses": [] "uses": []
}], }],

View File

@ -39,7 +39,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [8942920329766232482], "vars": [{
"L": 8942920329766232482,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["5:5-5:8|0|1|4"] "uses": ["5:5-5:8|0|1|4"]
}], }],

View File

@ -113,7 +113,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [15042442838933090518], "vars": [{
"L": 15042442838933090518,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["3:20-3:23|17805385787823406700|2|4", "9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"] "uses": ["3:20-3:23|17805385787823406700|2|4", "9:27-9:30|0|1|4", "12:21-12:24|10818727483146447186|3|4"]
}, { }, {

View File

@ -76,7 +76,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [17328473273923617489], "funcs": [17328473273923617489],
"vars": [12898699035586282159], "vars": [{
"L": 12898699035586282159,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["1:11-1:13|0|1|4", "7:3-7:5|631910859630953711|3|4", "7:14-7:16|631910859630953711|3|4", "8:19-8:21|631910859630953711|3|4"] "uses": ["1:11-1:13|0|1|4", "7:3-7:5|631910859630953711|3|4", "7:14-7:16|631910859630953711|3|4", "8:19-8:21|631910859630953711|3|4"]
}, { }, {

View File

@ -81,7 +81,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [12898699035586282159, 9008550860229740818], "vars": [{
"L": 12898699035586282159,
"R": -1
}, {
"L": 9008550860229740818,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["1:11-1:13|0|1|4"] "uses": ["1:11-1:13|0|1|4"]
}, { }, {
@ -98,7 +104,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [4731849186641714451], "vars": [{
"L": 4731849186641714451,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["10:26-10:32|0|1|4", "13:13-13:19|0|1|4", "14:14-14:20|0|1|4"] "uses": ["10:26-10:32|0|1|4", "13:13-13:19|0|1|4", "14:14-14:20|0|1|4"]
}, { }, {

View File

@ -70,7 +70,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [8905286151237717330], "funcs": [8905286151237717330],
"vars": [5866801090710377175], "vars": [{
"L": 5866801090710377175,
"R": -1
}],
"instances": [], "instances": [],
"uses": [] "uses": []
}, { }, {

View File

@ -62,7 +62,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [15768138241775955040, 3182917058194750998], "vars": [{
"L": 15768138241775955040,
"R": -1
}, {
"L": 3182917058194750998,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["1:11-1:13|0|1|4"] "uses": ["1:11-1:13|0|1|4"]
}, { }, {

View File

@ -26,7 +26,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [15768138241775955040, 3182917058194750998], "vars": [{
"L": 15768138241775955040,
"R": -1
}, {
"L": 3182917058194750998,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["1:11-1:13|0|1|4"] "uses": ["1:11-1:13|0|1|4"]
}, { }, {

View File

@ -38,7 +38,16 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [3348817847649945564, 4821094820988543895, 15292551660437765731], "vars": [{
"L": 3348817847649945564,
"R": 0
}, {
"L": 4821094820988543895,
"R": 32
}, {
"L": 15292551660437765731,
"R": 64
}],
"instances": [], "instances": [],
"uses": [] "uses": []
}, { }, {
@ -55,7 +64,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [1963212417280098348], "vars": [{
"L": 1963212417280098348,
"R": 0
}],
"instances": [], "instances": [],
"uses": [] "uses": []
}], }],

View File

@ -53,7 +53,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [9529311430721959843, 8804696910588009104], "vars": [{
"L": 9529311430721959843,
"R": 0
}, {
"L": 8804696910588009104,
"R": 0
}],
"instances": [], "instances": [],
"uses": [] "uses": []
}], }],

View File

@ -77,7 +77,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [9529311430721959843, 8804696910588009104], "vars": [{
"L": 9529311430721959843,
"R": 0
}, {
"L": 8804696910588009104,
"R": 0
}],
"instances": [2933643612409209903], "instances": [2933643612409209903],
"uses": ["6:1-6:4|0|1|4", "8:10-8:13|0|1|4"] "uses": ["6:1-6:4|0|1|4", "8:10-8:13|0|1|4"]
}], }],

View File

@ -57,7 +57,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [4220150017963593039], "vars": [{
"L": 4220150017963593039,
"R": 0
}],
"instances": [], "instances": [],
"uses": [] "uses": []
}], }],

View File

@ -58,7 +58,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [14314859014962085433, 14727441168849658842], "vars": [{
"L": 14314859014962085433,
"R": 0
}, {
"L": 14727441168849658842,
"R": 64
}],
"instances": [], "instances": [],
"uses": [] "uses": []
}], }],

View File

@ -93,7 +93,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [9648311402855509901, 11489549839875479478], "vars": [{
"L": 9648311402855509901,
"R": 0
}, {
"L": 11489549839875479478,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["10:5-10:8|0|1|4", "14:22-14:25|0|1|4", "14:40-14:43|0|1|4"] "uses": ["10:5-10:8|0|1|4", "14:22-14:25|0|1|4", "14:40-14:43|0|1|4"]
}], }],

View File

@ -96,7 +96,13 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [4220150017963593039, 3873837747174060388], "vars": [{
"L": 4220150017963593039,
"R": 0
}, {
"L": 3873837747174060388,
"R": 32
}],
"instances": [14669930844300034456], "instances": [14669930844300034456],
"uses": ["11:3-11:6|0|1|4"] "uses": ["11:3-11:6|0|1|4"]
}], }],

View File

@ -44,7 +44,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [7057400933868440116], "vars": [{
"L": 7057400933868440116,
"R": -1
}],
"instances": [], "instances": [],
"uses": ["7:15-7:21|0|1|4"] "uses": ["7:15-7:21|0|1|4"]
}], }],

View File

@ -21,7 +21,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [13799811842374292251], "vars": [{
"L": 13799811842374292251,
"R": 0
}],
"instances": [13799811842374292251], "instances": [13799811842374292251],
"uses": ["2:3-2:6|0|1|4"] "uses": ["2:3-2:6|0|1|4"]
}], }],

View File

@ -23,7 +23,10 @@ OUTPUT:
"derived": [], "derived": [],
"types": [], "types": [],
"funcs": [], "funcs": [],
"vars": [5844987037615239736], "vars": [{
"L": 5844987037615239736,
"R": -1
}],
"instances": [5844987037615239736], "instances": [5844987037615239736],
"uses": ["2:10-2:13|0|1|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"] "uses": ["2:10-2:13|0|1|4", "4:1-4:4|0|1|4", "4:6-4:9|0|1|4"]
}], }],

View File

@ -681,7 +681,7 @@ void OnIndexReference_Function(IndexFile* db,
} // namespace } // namespace
// static // static
const int IndexFile::kMajorVersion = 15; const int IndexFile::kMajorVersion = 16;
const int IndexFile::kMinorVersion = 0; const int IndexFile::kMinorVersion = 0;
IndexFile::IndexFile(const std::string& path, const std::string& contents) IndexFile::IndexFile(const std::string& path, const std::string& contents)
@ -1491,8 +1491,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
} }
case SymbolKind::Type: case SymbolKind::Type:
if (decl->semanticContainer->cursor.kind != CXCursor_EnumDecl) { if (decl->semanticContainer->cursor.kind != CXCursor_EnumDecl) {
long offset = clang_Cursor_getOffsetOfField(cursor.cx_cursor);
db->ToType(decl->semanticContainer->cursor) db->ToType(decl->semanticContainer->cursor)
.def.vars.push_back(var.usr); .def.vars.emplace_back(var.usr, offset);
} }
break; break;
default: default:

View File

@ -171,7 +171,7 @@ struct TypeDef : NameMixin<TypeDef> {
// Types, functions, and variables defined in this type. // Types, functions, and variables defined in this type.
std::vector<Usr> types; std::vector<Usr> types;
std::vector<Usr> funcs; std::vector<Usr> funcs;
std::vector<Usr> vars; std::vector<std::pair<Usr, int64_t>> vars;
// If set, then this is the same underlying type as the given value (ie, this // If set, then this is the same underlying type as the given value (ie, this
// type comes from a using or typedef statement). // type comes from a using or typedef statement).

View File

@ -74,17 +74,29 @@ bool Expand(MessageHandler* m,
void DoField(MessageHandler* m, void DoField(MessageHandler* m,
Out_CclsMemberHierarchy::Entry* entry, Out_CclsMemberHierarchy::Entry* entry,
const QueryVar& var, const QueryVar& var,
int64_t offset,
bool qualified, bool qualified,
int levels) { int levels) {
const QueryVar::Def* def1 = var.AnyDef(); const QueryVar::Def* def1 = var.AnyDef();
if (!def1) if (!def1)
return; return;
Out_CclsMemberHierarchy::Entry entry1; Out_CclsMemberHierarchy::Entry entry1;
// With multiple inheritance, the offset is incorrect.
if (offset >= 0) {
if (offset / 8 < 10)
entry1.fieldName += ' ';
entry1.fieldName += std::to_string(offset / 8);
if (offset % 8) {
entry1.fieldName += '.';
entry1.fieldName += std::to_string(offset % 8);
}
entry1.fieldName += ' ';
}
if (qualified) if (qualified)
entry1.fieldName = def1->detailed_name; entry1.fieldName += def1->detailed_name;
else else
entry1.fieldName = def1->detailed_name.substr(0, def1->qual_name_offset) + entry1.fieldName += def1->detailed_name.substr(0, def1->qual_name_offset) +
std::string(def1->Name(false)); std::string(def1->Name(false));
if (def1->spell) { if (def1->spell) {
if (std::optional<lsLocation> loc = if (std::optional<lsLocation> loc =
GetLsLocation(m->db, m->working_files, *def1->spell)) GetLsLocation(m->db, m->working_files, *def1->spell))
@ -158,9 +170,11 @@ bool Expand(MessageHandler* m,
entry->children.push_back(std::move(entry1)); entry->children.push_back(std::move(entry1));
} }
} else { } else {
EachDefinedEntity(m->db->usr2var, def->vars, [&](QueryVar& var) { for (auto it : def->vars) {
DoField(m, entry, var, qualified, levels - 1); QueryVar& var = m->db->usr2var[it.first];
}); if (!var.def.empty())
DoField(m, entry, var, it.second, qualified, levels - 1);
}
} }
} }
} }
@ -195,7 +209,7 @@ struct Handler_CclsMemberHierarchy
entry.location = *loc; entry.location = *loc;
} }
EachDefinedEntity(db->usr2var, def->vars, [&](QueryVar& var) { EachDefinedEntity(db->usr2var, def->vars, [&](QueryVar& var) {
DoField(this, &entry, var, qualified, levels - 1); DoField(this, &entry, var, -1, qualified, levels - 1);
}); });
return entry; return entry;
} }

View File

@ -80,7 +80,7 @@ struct Handler_CclsRandom : BaseMessageHandler<In_CclsRandom> {
Add<SymbolKind::Var>(sym2id, adj, it.second.instances, n); Add<SymbolKind::Var>(sym2id, adj, it.second.instances, n);
Add<SymbolKind::Func>(sym2id, adj, def->funcs, n); Add<SymbolKind::Func>(sym2id, adj, def->funcs, n);
Add<SymbolKind::Type>(sym2id, adj, def->types, n); Add<SymbolKind::Type>(sym2id, adj, def->types, n);
Add<SymbolKind::Var>(sym2id, adj, def->vars, n); //Add<SymbolKind::Var>(sym2id, adj, def->vars, n);
n++; n++;
} }
for (auto& it : db->usr2var) for (auto& it : db->usr2var)

View File

@ -269,9 +269,8 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
#endif #endif
} }
if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) {
LOG_S(INFO) << "unable to load " << Path.c_str() LOG_S(WARNING) << "unable to load " << Path.c_str();
<< "; using directory listing instead."; return {};
return LoadFromDirectoryListing(project);
} }
LOG_S(INFO) << "loaded " << Path.c_str(); LOG_S(INFO) << "loaded " << Path.c_str();

View File

@ -48,7 +48,7 @@ class Reader {
virtual std::unique_ptr<Reader> operator[](const char* x) = 0; virtual std::unique_ptr<Reader> operator[](const char* x) = 0;
virtual void IterArray(std::function<void(Reader&)> fn) = 0; virtual void IterArray(std::function<void(Reader&)> fn) = 0;
virtual void DoMember(const char* name, std::function<void(Reader&)> fn) = 0; virtual void Member(const char* name, std::function<void()> fn) = 0;
}; };
class Writer { class Writer {
@ -75,8 +75,8 @@ class Writer {
struct IndexFile; struct IndexFile;
#define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value) #define REFLECT_MEMBER_START() ReflectMemberStart(visitor)
#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value); #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor);
#define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name)
#define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ #define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \
ReflectMember(visitor, #name, value.name, mandatory_optional_tag{}) ReflectMember(visitor, #name, value.name, mandatory_optional_tag{})
@ -265,6 +265,19 @@ void ReflectMember(Writer& visitor,
Reflect(visitor, value); Reflect(visitor, value);
} }
template <typename L, typename R>
void Reflect(Reader& vis, std::pair<L, R>& v) {
vis.Member("L", [&]() { Reflect(vis, v.first); });
vis.Member("R", [&]() { Reflect(vis, v.second); });
}
template <typename L, typename R>
void Reflect(Writer& vis, std::pair<L, R>& v) {
vis.StartObject();
ReflectMember(vis, "L", v.first);
ReflectMember(vis, "R", v.second);
vis.EndObject();
}
// std::vector // std::vector
template <typename T> template <typename T>
void Reflect(Reader& visitor, std::vector<T>& values) { void Reflect(Reader& visitor, std::vector<T>& values) {
@ -284,31 +297,27 @@ void Reflect(Writer& visitor, std::vector<T>& values) {
// ReflectMember // ReflectMember
template <typename T> inline bool ReflectMemberStart(Reader& vis) {
bool ReflectMemberStart(Reader& visitor, T& value) {
return false; return false;
} }
template <typename T> inline bool ReflectMemberStart(Writer& vis) {
bool ReflectMemberStart(Writer& visitor, T& value) { vis.StartObject();
visitor.StartObject();
return true; return true;
} }
template <typename T> inline void ReflectMemberEnd(Reader& vis) {}
void ReflectMemberEnd(Reader& visitor, T& value) {} inline void ReflectMemberEnd(Writer& vis) {
template <typename T> vis.EndObject();
void ReflectMemberEnd(Writer& visitor, T& value) {
visitor.EndObject();
} }
template <typename T> template <typename T>
void ReflectMember(Reader& visitor, const char* name, T& value) { void ReflectMember(Reader& vis, const char* name, T& v) {
visitor.DoMember(name, [&](Reader& child) { Reflect(child, value); }); vis.Member(name, [&]() { Reflect(vis, v); });
} }
template <typename T> template <typename T>
void ReflectMember(Writer& visitor, const char* name, T& value) { void ReflectMember(Writer& vis, const char* name, T& v) {
visitor.Key(name); vis.Key(name);
Reflect(visitor, value); Reflect(vis, v);
} }
// API // API

View File

@ -39,10 +39,10 @@ class BinaryReader : public Reader {
// Abuse how the function is called in serializer.h // Abuse how the function is called in serializer.h
bool IsNull() override { return !*p_++; } bool IsNull() override { return !*p_++; }
bool IsInt() override { return true; } bool IsInt() override { return true; }
bool IsInt64() override {return true;} bool IsInt64() override { return true; }
bool IsUInt64() override {return true;} bool IsUInt64() override { return true; }
bool IsDouble() override {return true;}; bool IsDouble() override { return true; }
bool IsString() override {return true;} bool IsString() override { return true; }
void GetNull() override {} void GetNull() override {}
bool GetBool() override { return Get<bool>(); } bool GetBool() override { return Get<bool>(); }
@ -69,8 +69,8 @@ class BinaryReader : public Reader {
fn(*this); fn(*this);
} }
void DoMember(const char*, std::function<void(Reader&)> fn) override { void Member(const char*, std::function<void()> fn) override {
fn(*this); fn();
} }
}; };

View File

@ -51,13 +51,13 @@ class JsonReader : public Reader {
path_.pop_back(); path_.pop_back();
} }
void DoMember(const char* name, std::function<void(Reader&)> fn) override { void Member(const char* name, std::function<void()> fn) override {
path_.push_back(name); path_.push_back(name);
auto it = m_->FindMember(name); auto it = m_->FindMember(name);
if (it != m_->MemberEnd()) { if (it != m_->MemberEnd()) {
auto saved = m_; auto saved = m_;
m_ = &it->value; m_ = &it->value;
fn(*this); fn();
m_ = saved; m_ = saved;
} }
path_.pop_back(); path_.pop_back();