$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": [],
"types": [],
"funcs": [],
"vars": [9736582033442720743],
"vars": [{
"L": 9736582033442720743,
"R": 0
}],
"instances": [],
"uses": []
}],

View File

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

View File

@ -113,7 +113,10 @@ OUTPUT:
"derived": [],
"types": [],
"funcs": [],
"vars": [15042442838933090518],
"vars": [{
"L": 15042442838933090518,
"R": -1
}],
"instances": [],
"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": [],
"types": [],
"funcs": [17328473273923617489],
"vars": [12898699035586282159],
"vars": [{
"L": 12898699035586282159,
"R": -1
}],
"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"]
}, {

View File

@ -81,7 +81,13 @@ OUTPUT:
"derived": [],
"types": [],
"funcs": [],
"vars": [12898699035586282159, 9008550860229740818],
"vars": [{
"L": 12898699035586282159,
"R": -1
}, {
"L": 9008550860229740818,
"R": -1
}],
"instances": [],
"uses": ["1:11-1:13|0|1|4"]
}, {
@ -98,7 +104,10 @@ OUTPUT:
"derived": [],
"types": [],
"funcs": [],
"vars": [4731849186641714451],
"vars": [{
"L": 4731849186641714451,
"R": -1
}],
"instances": [],
"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": [],
"types": [],
"funcs": [8905286151237717330],
"vars": [5866801090710377175],
"vars": [{
"L": 5866801090710377175,
"R": -1
}],
"instances": [],
"uses": []
}, {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -93,7 +93,13 @@ OUTPUT:
"derived": [],
"types": [],
"funcs": [],
"vars": [9648311402855509901, 11489549839875479478],
"vars": [{
"L": 9648311402855509901,
"R": 0
}, {
"L": 11489549839875479478,
"R": -1
}],
"instances": [],
"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": [],
"types": [],
"funcs": [],
"vars": [4220150017963593039, 3873837747174060388],
"vars": [{
"L": 4220150017963593039,
"R": 0
}, {
"L": 3873837747174060388,
"R": 32
}],
"instances": [14669930844300034456],
"uses": ["11:3-11:6|0|1|4"]
}],

View File

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

View File

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

View File

@ -23,7 +23,10 @@ OUTPUT:
"derived": [],
"types": [],
"funcs": [],
"vars": [5844987037615239736],
"vars": [{
"L": 5844987037615239736,
"R": -1
}],
"instances": [5844987037615239736],
"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
// static
const int IndexFile::kMajorVersion = 15;
const int IndexFile::kMajorVersion = 16;
const int IndexFile::kMinorVersion = 0;
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:
if (decl->semanticContainer->cursor.kind != CXCursor_EnumDecl) {
long offset = clang_Cursor_getOffsetOfField(cursor.cx_cursor);
db->ToType(decl->semanticContainer->cursor)
.def.vars.push_back(var.usr);
.def.vars.emplace_back(var.usr, offset);
}
break;
default:

View File

@ -171,7 +171,7 @@ struct TypeDef : NameMixin<TypeDef> {
// Types, functions, and variables defined in this type.
std::vector<Usr> types;
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
// type comes from a using or typedef statement).

View File

@ -74,16 +74,28 @@ bool Expand(MessageHandler* m,
void DoField(MessageHandler* m,
Out_CclsMemberHierarchy::Entry* entry,
const QueryVar& var,
int64_t offset,
bool qualified,
int levels) {
const QueryVar::Def* def1 = var.AnyDef();
if (!def1)
return;
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)
entry1.fieldName = def1->detailed_name;
entry1.fieldName += def1->detailed_name;
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));
if (def1->spell) {
if (std::optional<lsLocation> loc =
@ -158,9 +170,11 @@ bool Expand(MessageHandler* m,
entry->children.push_back(std::move(entry1));
}
} else {
EachDefinedEntity(m->db->usr2var, def->vars, [&](QueryVar& var) {
DoField(m, entry, var, qualified, levels - 1);
});
for (auto it : def->vars) {
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;
}
EachDefinedEntity(db->usr2var, def->vars, [&](QueryVar& var) {
DoField(this, &entry, var, qualified, levels - 1);
DoField(this, &entry, var, -1, qualified, levels - 1);
});
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::Func>(sym2id, adj, def->funcs, 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++;
}
for (auto& it : db->usr2var)

View File

@ -269,9 +269,8 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
#endif
}
if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) {
LOG_S(INFO) << "unable to load " << Path.c_str()
<< "; using directory listing instead.";
return LoadFromDirectoryListing(project);
LOG_S(WARNING) << "unable to load " << Path.c_str();
return {};
}
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 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 {
@ -75,8 +75,8 @@ class Writer {
struct IndexFile;
#define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value)
#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value);
#define REFLECT_MEMBER_START() ReflectMemberStart(visitor)
#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor);
#define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name)
#define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \
ReflectMember(visitor, #name, value.name, mandatory_optional_tag{})
@ -265,6 +265,19 @@ void ReflectMember(Writer& visitor,
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
template <typename T>
void Reflect(Reader& visitor, std::vector<T>& values) {
@ -284,31 +297,27 @@ void Reflect(Writer& visitor, std::vector<T>& values) {
// ReflectMember
template <typename T>
bool ReflectMemberStart(Reader& visitor, T& value) {
inline bool ReflectMemberStart(Reader& vis) {
return false;
}
template <typename T>
bool ReflectMemberStart(Writer& visitor, T& value) {
visitor.StartObject();
inline bool ReflectMemberStart(Writer& vis) {
vis.StartObject();
return true;
}
template <typename T>
void ReflectMemberEnd(Reader& visitor, T& value) {}
template <typename T>
void ReflectMemberEnd(Writer& visitor, T& value) {
visitor.EndObject();
inline void ReflectMemberEnd(Reader& vis) {}
inline void ReflectMemberEnd(Writer& vis) {
vis.EndObject();
}
template <typename T>
void ReflectMember(Reader& visitor, const char* name, T& value) {
visitor.DoMember(name, [&](Reader& child) { Reflect(child, value); });
void ReflectMember(Reader& vis, const char* name, T& v) {
vis.Member(name, [&]() { Reflect(vis, v); });
}
template <typename T>
void ReflectMember(Writer& visitor, const char* name, T& value) {
visitor.Key(name);
Reflect(visitor, value);
void ReflectMember(Writer& vis, const char* name, T& v) {
vis.Key(name);
Reflect(vis, v);
}
// API

View File

@ -41,7 +41,7 @@ class BinaryReader : public Reader {
bool IsInt() override { return true; }
bool IsInt64() override { return true; }
bool IsUInt64() override { return true; }
bool IsDouble() override {return true;};
bool IsDouble() override { return true; }
bool IsString() override { return true; }
void GetNull() override {}
@ -69,8 +69,8 @@ class BinaryReader : public Reader {
fn(*this);
}
void DoMember(const char*, std::function<void(Reader&)> fn) override {
fn(*this);
void Member(const char*, std::function<void()> fn) override {
fn();
}
};

View File

@ -51,13 +51,13 @@ class JsonReader : public Reader {
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);
auto it = m_->FindMember(name);
if (it != m_->MemberEnd()) {
auto saved = m_;
m_ = &it->value;
fn(*this);
fn();
m_ = saved;
}
path_.pop_back();