mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 10:02:03 +00:00
Add GetAdjustedDecl to adjust Decl's that are missed by clangIndex
This commit is contained in:
parent
35cba6d49c
commit
5b7758a6ca
@ -215,8 +215,8 @@ OUTPUT: impl.cc
|
||||
"callees": ["4:3-4:7|11650481237659640387|3|16420"]
|
||||
}, {
|
||||
"usr": 11650481237659640387,
|
||||
"detailed_name": "template<> void Foo1<int>()",
|
||||
"qual_name_offset": 16,
|
||||
"detailed_name": "void Foo1()",
|
||||
"qual_name_offset": 5,
|
||||
"short_name": "Foo1",
|
||||
"kind": 12,
|
||||
"storage": 0,
|
||||
|
@ -50,8 +50,8 @@ OUTPUT: static.cc
|
||||
"skipped_ranges": [],
|
||||
"usr2func": [{
|
||||
"usr": 14576076421851654759,
|
||||
"detailed_name": "void Buffer::CreateSharedBuffer()",
|
||||
"qual_name_offset": 5,
|
||||
"detailed_name": "static void Buffer::CreateSharedBuffer()",
|
||||
"qual_name_offset": 12,
|
||||
"short_name": "CreateSharedBuffer",
|
||||
"kind": 254,
|
||||
"storage": 0,
|
||||
|
@ -84,8 +84,8 @@ OUTPUT: static_function_in_type.cc
|
||||
"skipped_ranges": [],
|
||||
"usr2func": [{
|
||||
"usr": 17019747379608639279,
|
||||
"detailed_name": "void Foo::Register(ns::Manager *m)",
|
||||
"qual_name_offset": 5,
|
||||
"detailed_name": "static void ns::Foo::Register(ns::Manager *)",
|
||||
"qual_name_offset": 12,
|
||||
"short_name": "Register",
|
||||
"kind": 254,
|
||||
"storage": 0,
|
||||
|
@ -29,21 +29,6 @@ OUTPUT:
|
||||
"callees": []
|
||||
}],
|
||||
"usr2type": [{
|
||||
"usr": 2100211316767379401,
|
||||
"detailed_name": "template<> class Template<double>",
|
||||
"qual_name_offset": 17,
|
||||
"short_name": "Template",
|
||||
"kind": 5,
|
||||
"declarations": [],
|
||||
"alias_of": 0,
|
||||
"bases": [],
|
||||
"derived": [],
|
||||
"types": [],
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 15041163540773201510,
|
||||
"detailed_name": "struct Foo {}",
|
||||
"qual_name_offset": 7,
|
||||
@ -76,7 +61,7 @@ OUTPUT:
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": []
|
||||
"uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"]
|
||||
}],
|
||||
"usr2var": []
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ OUTPUT:
|
||||
"skipped_ranges": [],
|
||||
"usr2func": [{
|
||||
"usr": 6995843774014807426,
|
||||
"detailed_name": "template <> void Template<void>::Foo()",
|
||||
"qual_name_offset": 31,
|
||||
"detailed_name": "void Template<void>::Foo()",
|
||||
"qual_name_offset": 5,
|
||||
"short_name": "Foo",
|
||||
"kind": 6,
|
||||
"storage": 0,
|
||||
|
@ -159,21 +159,6 @@ OUTPUT:
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["15:30-15:32|0|1|4|-1", "33:23-33:25|0|1|4|-1", "33:63-33:65|0|1|4|-1", "54:25-54:27|18320186404467436976|3|4|-1", "65:14-65:16|15041163540773201510|2|4|-1", "79:12-79:14|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 7147635971744144194,
|
||||
"detailed_name": "template<> class unique_ptr<S1, S2>",
|
||||
"qual_name_offset": 17,
|
||||
"short_name": "unique_ptr",
|
||||
"kind": 5,
|
||||
"declarations": [],
|
||||
"alias_of": 0,
|
||||
"bases": [],
|
||||
"derived": [],
|
||||
"types": [],
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["15:19-15:29|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 12728490517004312484,
|
||||
"detailed_name": "struct S2",
|
||||
@ -203,7 +188,7 @@ OUTPUT:
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [2933643612409209903, 500112618220246],
|
||||
"uses": []
|
||||
"uses": ["15:8-15:18|0|1|4|-1", "15:19-15:29|0|1|4|-1", "33:1-33:11|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 15041163540773201510,
|
||||
"detailed_name": "class Foo {}",
|
||||
@ -221,21 +206,6 @@ OUTPUT:
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["79:21-79:24|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 18153735331422331128,
|
||||
"detailed_name": "template<> class unique_ptr<unique_ptr<S1, S2>, S2>",
|
||||
"qual_name_offset": 17,
|
||||
"short_name": "unique_ptr",
|
||||
"kind": 5,
|
||||
"declarations": [],
|
||||
"alias_of": 0,
|
||||
"bases": [],
|
||||
"derived": [],
|
||||
"types": [],
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["15:8-15:18|0|1|4|-1", "33:1-33:11|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1"]
|
||||
}],
|
||||
"usr2var": [{
|
||||
"usr": 500112618220246,
|
||||
|
@ -19,7 +19,7 @@ OUTPUT:
|
||||
"declarations": [],
|
||||
"spell": "4:7-4:11|0|1|2|-1",
|
||||
"extent": "4:1-4:22|0|1|0|-1",
|
||||
"alias_of": 5123806965838456033,
|
||||
"alias_of": 10528472276654770367,
|
||||
"bases": [],
|
||||
"derived": [],
|
||||
"types": [],
|
||||
@ -27,27 +27,12 @@ OUTPUT:
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["5:13-5:17|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 5123806965838456033,
|
||||
"detailed_name": "template<> struct Foo<int>",
|
||||
"qual_name_offset": 18,
|
||||
"short_name": "Foo",
|
||||
"kind": 5,
|
||||
"declarations": [],
|
||||
"alias_of": 0,
|
||||
"bases": [],
|
||||
"derived": [],
|
||||
"types": [],
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["4:14-4:17|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 10528472276654770367,
|
||||
"detailed_name": "struct Foo",
|
||||
"qual_name_offset": 7,
|
||||
"short_name": "Foo",
|
||||
"kind": 23,
|
||||
"kind": 5,
|
||||
"declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"],
|
||||
"alias_of": 0,
|
||||
"bases": [],
|
||||
@ -56,22 +41,7 @@ OUTPUT:
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": []
|
||||
}, {
|
||||
"usr": 14491685842684954828,
|
||||
"detailed_name": "template<> struct Foo<Foo<int>>",
|
||||
"qual_name_offset": 18,
|
||||
"short_name": "Foo",
|
||||
"kind": 5,
|
||||
"declarations": [],
|
||||
"alias_of": 0,
|
||||
"bases": [],
|
||||
"derived": [],
|
||||
"types": [],
|
||||
"funcs": [],
|
||||
"vars": [],
|
||||
"instances": [],
|
||||
"uses": ["5:9-5:12|0|1|4|-1"]
|
||||
"uses": ["4:14-4:17|0|1|4|-1", "5:9-5:12|0|1|4|-1"]
|
||||
}, {
|
||||
"usr": 15933698173231330933,
|
||||
"detailed_name": "typedef Foo<Foo1> Foo2",
|
||||
@ -81,7 +51,7 @@ OUTPUT:
|
||||
"declarations": [],
|
||||
"spell": "5:19-5:23|0|1|2|-1",
|
||||
"extent": "5:1-5:23|0|1|0|-1",
|
||||
"alias_of": 14491685842684954828,
|
||||
"alias_of": 10528472276654770367,
|
||||
"bases": [],
|
||||
"derived": [],
|
||||
"types": [],
|
||||
|
154
src/indexer.cc
154
src/indexer.cc
@ -284,6 +284,35 @@ try_again:
|
||||
return D;
|
||||
}
|
||||
|
||||
const Decl *GetAdjustedDecl(const Decl *D) {
|
||||
while (D) {
|
||||
if (auto *R = dyn_cast<CXXRecordDecl>(D)) {
|
||||
if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(R)) {
|
||||
if (!S->getTypeAsWritten()) {
|
||||
llvm::PointerUnion<ClassTemplateDecl *,
|
||||
ClassTemplatePartialSpecializationDecl *>
|
||||
Result = S->getSpecializedTemplateOrPartial();
|
||||
if (Result.is<ClassTemplateDecl *>())
|
||||
D = Result.get<ClassTemplateDecl *>();
|
||||
else
|
||||
D = Result.get<ClassTemplatePartialSpecializationDecl *>();
|
||||
continue;
|
||||
}
|
||||
} else if (auto *D1 = R->getInstantiatedFromMemberClass()) {
|
||||
D = D1;
|
||||
continue;
|
||||
}
|
||||
} else if (auto *ED = dyn_cast<EnumDecl>(D)) {
|
||||
if (auto *D1 = ED->getInstantiatedFromMemberEnum()) {
|
||||
D = D1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return D;
|
||||
}
|
||||
|
||||
bool ValidateRecord(const RecordDecl *RD) {
|
||||
for (const auto *I : RD->fields()) {
|
||||
QualType FQT = I->getType();
|
||||
@ -621,11 +650,12 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
// spell, extent, comments use OrigD while most others use adjusted |D|.
|
||||
const Decl *OrigD = ASTNode.OrigD;
|
||||
const DeclContext *SemDC = OrigD->getDeclContext();
|
||||
const DeclContext *LexDC = ASTNode.ContainerDC;
|
||||
Role role = static_cast<Role>(Roles);
|
||||
db->language = LanguageId((int)db->language | (int)GetDeclLanguage(OrigD));
|
||||
db->language = LanguageId((int)db->language | (int)GetDeclLanguage(D));
|
||||
|
||||
bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration);
|
||||
bool is_def = Roles & uint32_t(index::SymbolRole::Definition);
|
||||
@ -635,11 +665,9 @@ public:
|
||||
IndexType *type = nullptr;
|
||||
IndexVar *var = nullptr;
|
||||
SymbolKind kind = GetSymbolKind(D);
|
||||
IndexParam::DeclInfo *info;
|
||||
Usr usr = GetUsr(D, &info);
|
||||
|
||||
if (is_def)
|
||||
switch (OrigD->getKind()) {
|
||||
switch (D->getKind()) {
|
||||
case Decl::CXXConversion: // *operator* int => *operator int*
|
||||
case Decl::CXXDestructor: // *~*A => *~A*
|
||||
case Decl::CXXMethod: // *operator*= => *operator=*
|
||||
@ -654,6 +682,15 @@ public:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// e.g. typedef Foo<int> gg; => Foo has an unadjusted `D`
|
||||
const Decl *D1 = GetAdjustedDecl(D);
|
||||
if (D1 && D1 != D)
|
||||
D = D1;
|
||||
}
|
||||
|
||||
IndexParam::DeclInfo *info;
|
||||
Usr usr = GetUsr(D, &info);
|
||||
|
||||
auto do_def_decl = [&](auto *entity) {
|
||||
if (is_def) {
|
||||
@ -693,7 +730,7 @@ public:
|
||||
if (Spell != Loc)
|
||||
AddMacroUse(db, SM, usr, SymbolKind::Func, Spell);
|
||||
if (func->def.detailed_name[0] == '\0')
|
||||
SetName(OrigD, info->short_name, info->qualified, func->def);
|
||||
SetName(D, info->short_name, info->qualified, func->def);
|
||||
if (is_def || is_decl) {
|
||||
const Decl *DC = cast<Decl>(SemDC);
|
||||
if (GetSymbolKind(DC) == SymbolKind::Type)
|
||||
@ -711,7 +748,7 @@ public:
|
||||
if (Spell != Loc)
|
||||
AddMacroUse(db, SM, usr, SymbolKind::Type, Spell);
|
||||
if (type->def.detailed_name[0] == '\0' && info->short_name.size())
|
||||
SetName(OrigD, info->short_name, info->qualified, type->def);
|
||||
SetName(D, info->short_name, info->qualified, type->def);
|
||||
if (is_def || is_decl) {
|
||||
const Decl *DC = cast<Decl>(SemDC);
|
||||
if (GetSymbolKind(DC) == SymbolKind::Type)
|
||||
@ -724,7 +761,7 @@ public:
|
||||
if (Spell != Loc)
|
||||
AddMacroUse(db, SM, usr, SymbolKind::Var, Spell);
|
||||
if (var->def.detailed_name[0] == '\0')
|
||||
SetVarName(OrigD, info->short_name, info->qualified, var->def);
|
||||
SetVarName(D, info->short_name, info->qualified, var->def);
|
||||
QualType T;
|
||||
if (auto *VD = dyn_cast<VarDecl>(D))
|
||||
T = VD->getType();
|
||||
@ -741,63 +778,44 @@ public:
|
||||
Usr usr1 = static_cast<Usr>(BT->getKind());
|
||||
var->def.type = usr1;
|
||||
db->ToType(usr1).instances.push_back(usr);
|
||||
} else {
|
||||
for (const Decl *D1 = GetTypeDecl(T); D1; ) {
|
||||
if (auto *R1 = dyn_cast<CXXRecordDecl>(D1)) {
|
||||
if (auto *S1 = dyn_cast<ClassTemplateSpecializationDecl>(D1)) {
|
||||
if (!S1->getTypeAsWritten()) {
|
||||
llvm::PointerUnion<ClassTemplateDecl *,
|
||||
ClassTemplatePartialSpecializationDecl *>
|
||||
Result = S1->getSpecializedTemplateOrPartial();
|
||||
if (Result.is<ClassTemplateDecl *>())
|
||||
D1 = Result.get<ClassTemplateDecl *>();
|
||||
else
|
||||
D1 = Result.get<ClassTemplatePartialSpecializationDecl *>();
|
||||
continue;
|
||||
}
|
||||
} else if (auto *D2 = R1->getInstantiatedFromMemberClass()) {
|
||||
D1 = D2;
|
||||
continue;
|
||||
}
|
||||
} else if (auto *TP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
|
||||
// e.g. TemplateTypeParmDecl is not handled by
|
||||
// handleDeclOccurence.
|
||||
SourceRange R1 = D1->getSourceRange();
|
||||
if (SM.getFileID(R1.getBegin()) == LocFID) {
|
||||
IndexParam::DeclInfo *info1;
|
||||
Usr usr1 = GetUsr(D1, &info1);
|
||||
IndexType &type1 = db->ToType(usr1);
|
||||
SourceLocation L1 = D1->getLocation();
|
||||
type1.def.spell =
|
||||
GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC,
|
||||
Role::Definition);
|
||||
type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1),
|
||||
LexDC, Role::None);
|
||||
type1.def.detailed_name = Intern(info1->short_name);
|
||||
type1.def.short_name_size = int16_t(info1->short_name.size());
|
||||
type1.def.kind = lsSymbolKind::TypeParameter;
|
||||
var->def.type = usr1;
|
||||
type1.instances.push_back(usr);
|
||||
break;
|
||||
}
|
||||
} else if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T))) {
|
||||
if (isa<TemplateTypeParmDecl>(D1)) {
|
||||
// e.g. TemplateTypeParmDecl is not handled by
|
||||
// handleDeclOccurence.
|
||||
SourceRange R1 = D1->getSourceRange();
|
||||
if (SM.getFileID(R1.getBegin()) == LocFID) {
|
||||
IndexParam::DeclInfo *info1;
|
||||
Usr usr1 = GetUsr(D1, &info1);
|
||||
IndexType &type1 = db->ToType(usr1);
|
||||
SourceLocation L1 = D1->getLocation();
|
||||
type1.def.spell =
|
||||
GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC,
|
||||
Role::Definition);
|
||||
type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1),
|
||||
LexDC, Role::None);
|
||||
type1.def.detailed_name = Intern(info1->short_name);
|
||||
type1.def.short_name_size = int16_t(info1->short_name.size());
|
||||
type1.def.kind = lsSymbolKind::TypeParameter;
|
||||
var->def.type = usr1;
|
||||
type1.instances.push_back(usr);
|
||||
break;
|
||||
}
|
||||
|
||||
IndexParam::DeclInfo *info1;
|
||||
Usr usr1 = GetUsr(D1, &info1);
|
||||
var->def.type = usr1;
|
||||
db->ToType(usr1).instances.push_back(usr);
|
||||
break;
|
||||
}
|
||||
|
||||
IndexParam::DeclInfo *info1;
|
||||
Usr usr1 = GetUsr(D1, &info1);
|
||||
var->def.type = usr1;
|
||||
db->ToType(usr1).instances.push_back(usr);
|
||||
}
|
||||
}
|
||||
} else if (!var->def.spell && var->declarations.empty()) {
|
||||
// e.g. lambda parameter
|
||||
SourceLocation L = OrigD->getLocation();
|
||||
SourceLocation L = D->getLocation();
|
||||
if (SM.getFileID(L) == LocFID) {
|
||||
var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}),
|
||||
SemDC, Role::Definition);
|
||||
var->def.extent =
|
||||
GetUse(db, lid, FromTokenRange(SM, Lang, OrigD->getSourceRange()),
|
||||
GetUse(db, lid, FromTokenRange(SM, Lang, D->getSourceRange()),
|
||||
LexDC, Role::None);
|
||||
}
|
||||
}
|
||||
@ -807,8 +825,8 @@ public:
|
||||
switch (D->getKind()) {
|
||||
case Decl::Namespace:
|
||||
type->def.kind = lsSymbolKind::Namespace;
|
||||
if (OrigD->isFirstDecl()) {
|
||||
auto *ND = cast<NamespaceDecl>(OrigD);
|
||||
if (D->isFirstDecl()) {
|
||||
auto *ND = cast<NamespaceDecl>(D);
|
||||
auto *ND1 = cast<Decl>(ND->getParent());
|
||||
if (isa<NamespaceDecl>(ND1)) {
|
||||
Usr usr1 = GetUsr(ND1);
|
||||
@ -859,29 +877,19 @@ public:
|
||||
break;
|
||||
case Decl::CXXRecord:
|
||||
if (is_def) {
|
||||
auto *RD = dyn_cast<CXXRecordDecl>(OrigD);
|
||||
if (RD && RD->hasDefinition()) {
|
||||
for (const CXXBaseSpecifier &Base : RD->bases()) {
|
||||
QualType T = Base.getType();
|
||||
const NamedDecl *BaseD = nullptr;
|
||||
if (auto *TDT = T->getAs<TypedefType>()) {
|
||||
BaseD = TDT->getDecl();
|
||||
} else if (auto *TST = T->getAs<TemplateSpecializationType>()) {
|
||||
BaseD = TST->getTemplateName().getAsTemplateDecl();
|
||||
} else if (auto *RT = T->getAs<RecordType>()) {
|
||||
BaseD = RT->getDecl();
|
||||
}
|
||||
if (BaseD) {
|
||||
auto *RD = dyn_cast<CXXRecordDecl>(D);
|
||||
if (RD && RD->hasDefinition())
|
||||
for (const CXXBaseSpecifier &Base : RD->bases())
|
||||
if (const Decl *BaseD =
|
||||
GetAdjustedDecl(GetTypeDecl(Base.getType()))) {
|
||||
Usr usr1 = GetUsr(BaseD);
|
||||
type->def.bases.push_back(usr1);
|
||||
db->ToType(usr1).derived.push_back(usr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
case Decl::Record:
|
||||
if (auto *RD = dyn_cast<RecordDecl>(OrigD)) {
|
||||
if (auto *RD = dyn_cast<RecordDecl>(D)) {
|
||||
// spec has no Union, use Class
|
||||
type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct
|
||||
: lsSymbolKind::Class;
|
||||
@ -964,7 +972,7 @@ public:
|
||||
if (auto *TD = dyn_cast<TypedefNameDecl>(D)) {
|
||||
bool specialization = false;
|
||||
QualType T = TD->getUnderlyingType();
|
||||
if (const Decl *D1 = GetTypeDecl(T, &specialization)) {
|
||||
if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T, &specialization))) {
|
||||
Usr usr1 = GetUsr(D1);
|
||||
IndexType &type1 = db->ToType(usr1);
|
||||
type->def.alias_of = usr1;
|
||||
|
Loading…
Reference in New Issue
Block a user