Add GetAdjustedDecl to adjust Decl's that are missed by clangIndex

This commit is contained in:
Fangrui Song 2018-09-23 16:15:10 -07:00
parent 3334b2c4b7
commit d5f4f22508
8 changed files with 95 additions and 162 deletions

View File

@ -215,8 +215,8 @@ OUTPUT: impl.cc
"callees": ["4:3-4:7|11650481237659640387|3|16420"] "callees": ["4:3-4:7|11650481237659640387|3|16420"]
}, { }, {
"usr": 11650481237659640387, "usr": 11650481237659640387,
"detailed_name": "template<> void Foo1<int>()", "detailed_name": "void Foo1()",
"qual_name_offset": 16, "qual_name_offset": 5,
"short_name": "Foo1", "short_name": "Foo1",
"kind": 12, "kind": 12,
"storage": 0, "storage": 0,

View File

@ -50,8 +50,8 @@ OUTPUT: static.cc
"skipped_ranges": [], "skipped_ranges": [],
"usr2func": [{ "usr2func": [{
"usr": 14576076421851654759, "usr": 14576076421851654759,
"detailed_name": "void Buffer::CreateSharedBuffer()", "detailed_name": "static void Buffer::CreateSharedBuffer()",
"qual_name_offset": 5, "qual_name_offset": 12,
"short_name": "CreateSharedBuffer", "short_name": "CreateSharedBuffer",
"kind": 254, "kind": 254,
"storage": 0, "storage": 0,

View File

@ -84,8 +84,8 @@ OUTPUT: static_function_in_type.cc
"skipped_ranges": [], "skipped_ranges": [],
"usr2func": [{ "usr2func": [{
"usr": 17019747379608639279, "usr": 17019747379608639279,
"detailed_name": "void Foo::Register(ns::Manager *m)", "detailed_name": "static void ns::Foo::Register(ns::Manager *)",
"qual_name_offset": 5, "qual_name_offset": 12,
"short_name": "Register", "short_name": "Register",
"kind": 254, "kind": 254,
"storage": 0, "storage": 0,

View File

@ -29,21 +29,6 @@ OUTPUT:
"callees": [] "callees": []
}], }],
"usr2type": [{ "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, "usr": 15041163540773201510,
"detailed_name": "struct Foo {}", "detailed_name": "struct Foo {}",
"qual_name_offset": 7, "qual_name_offset": 7,
@ -76,7 +61,7 @@ OUTPUT:
"funcs": [], "funcs": [],
"vars": [], "vars": [],
"instances": [], "instances": [],
"uses": [] "uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"]
}], }],
"usr2var": [] "usr2var": []
} }

View File

@ -24,8 +24,8 @@ OUTPUT:
"skipped_ranges": [], "skipped_ranges": [],
"usr2func": [{ "usr2func": [{
"usr": 6995843774014807426, "usr": 6995843774014807426,
"detailed_name": "template <> void Template<void>::Foo()", "detailed_name": "void Template<void>::Foo()",
"qual_name_offset": 31, "qual_name_offset": 5,
"short_name": "Foo", "short_name": "Foo",
"kind": 6, "kind": 6,
"storage": 0, "storage": 0,

View File

@ -159,21 +159,6 @@ OUTPUT:
"vars": [], "vars": [],
"instances": [], "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"] "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, "usr": 12728490517004312484,
"detailed_name": "struct S2", "detailed_name": "struct S2",
@ -203,7 +188,7 @@ OUTPUT:
"funcs": [], "funcs": [],
"vars": [], "vars": [],
"instances": [2933643612409209903, 500112618220246], "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, "usr": 15041163540773201510,
"detailed_name": "class Foo {}", "detailed_name": "class Foo {}",
@ -221,21 +206,6 @@ OUTPUT:
"vars": [], "vars": [],
"instances": [], "instances": [],
"uses": ["79:21-79:24|0|1|4|-1"] "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": [{ "usr2var": [{
"usr": 500112618220246, "usr": 500112618220246,

View File

@ -19,7 +19,7 @@ OUTPUT:
"declarations": [], "declarations": [],
"spell": "4:7-4:11|0|1|2|-1", "spell": "4:7-4:11|0|1|2|-1",
"extent": "4:1-4:22|0|1|0|-1", "extent": "4:1-4:22|0|1|0|-1",
"alias_of": 5123806965838456033, "alias_of": 10528472276654770367,
"bases": [], "bases": [],
"derived": [], "derived": [],
"types": [], "types": [],
@ -27,27 +27,12 @@ OUTPUT:
"vars": [], "vars": [],
"instances": [], "instances": [],
"uses": ["5:13-5:17|0|1|4|-1"] "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, "usr": 10528472276654770367,
"detailed_name": "struct Foo", "detailed_name": "struct Foo",
"qual_name_offset": 7, "qual_name_offset": 7,
"short_name": "Foo", "short_name": "Foo",
"kind": 23, "kind": 5,
"declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"], "declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"],
"alias_of": 0, "alias_of": 0,
"bases": [], "bases": [],
@ -56,22 +41,7 @@ OUTPUT:
"funcs": [], "funcs": [],
"vars": [], "vars": [],
"instances": [], "instances": [],
"uses": [] "uses": ["4:14-4:17|0|1|4|-1", "5:9-5:12|0|1|4|-1"]
}, {
"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"]
}, { }, {
"usr": 15933698173231330933, "usr": 15933698173231330933,
"detailed_name": "typedef Foo<Foo1> Foo2", "detailed_name": "typedef Foo<Foo1> Foo2",
@ -81,7 +51,7 @@ OUTPUT:
"declarations": [], "declarations": [],
"spell": "5:19-5:23|0|1|2|-1", "spell": "5:19-5:23|0|1|2|-1",
"extent": "5:1-5:23|0|1|0|-1", "extent": "5:1-5:23|0|1|0|-1",
"alias_of": 14491685842684954828, "alias_of": 10528472276654770367,
"bases": [], "bases": [],
"derived": [], "derived": [],
"types": [], "types": [],

View File

@ -284,6 +284,35 @@ try_again:
return D; 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) { bool ValidateRecord(const RecordDecl *RD) {
for (const auto *I : RD->fields()) { for (const auto *I : RD->fields()) {
QualType FQT = I->getType(); QualType FQT = I->getType();
@ -621,11 +650,12 @@ public:
return true; return true;
} }
// spell, extent, comments use OrigD while most others use adjusted |D|.
const Decl *OrigD = ASTNode.OrigD; const Decl *OrigD = ASTNode.OrigD;
const DeclContext *SemDC = OrigD->getDeclContext(); const DeclContext *SemDC = OrigD->getDeclContext();
const DeclContext *LexDC = ASTNode.ContainerDC; const DeclContext *LexDC = ASTNode.ContainerDC;
Role role = static_cast<Role>(Roles); 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_decl = Roles & uint32_t(index::SymbolRole::Declaration);
bool is_def = Roles & uint32_t(index::SymbolRole::Definition); bool is_def = Roles & uint32_t(index::SymbolRole::Definition);
@ -635,11 +665,9 @@ public:
IndexType *type = nullptr; IndexType *type = nullptr;
IndexVar *var = nullptr; IndexVar *var = nullptr;
SymbolKind kind = GetSymbolKind(D); SymbolKind kind = GetSymbolKind(D);
IndexParam::DeclInfo *info;
Usr usr = GetUsr(D, &info);
if (is_def) if (is_def)
switch (OrigD->getKind()) { switch (D->getKind()) {
case Decl::CXXConversion: // *operator* int => *operator int* case Decl::CXXConversion: // *operator* int => *operator int*
case Decl::CXXDestructor: // *~*A => *~A* case Decl::CXXDestructor: // *~*A => *~A*
case Decl::CXXMethod: // *operator*= => *operator=* case Decl::CXXMethod: // *operator*= => *operator=*
@ -654,6 +682,15 @@ public:
default: default:
break; 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) { auto do_def_decl = [&](auto *entity) {
if (is_def) { if (is_def) {
@ -693,7 +730,7 @@ public:
if (Spell != Loc) if (Spell != Loc)
AddMacroUse(db, SM, usr, SymbolKind::Func, Spell); AddMacroUse(db, SM, usr, SymbolKind::Func, Spell);
if (func->def.detailed_name[0] == '\0') 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) { if (is_def || is_decl) {
const Decl *DC = cast<Decl>(SemDC); const Decl *DC = cast<Decl>(SemDC);
if (GetSymbolKind(DC) == SymbolKind::Type) if (GetSymbolKind(DC) == SymbolKind::Type)
@ -711,7 +748,7 @@ public:
if (Spell != Loc) if (Spell != Loc)
AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); AddMacroUse(db, SM, usr, SymbolKind::Type, Spell);
if (type->def.detailed_name[0] == '\0' && info->short_name.size()) 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) { if (is_def || is_decl) {
const Decl *DC = cast<Decl>(SemDC); const Decl *DC = cast<Decl>(SemDC);
if (GetSymbolKind(DC) == SymbolKind::Type) if (GetSymbolKind(DC) == SymbolKind::Type)
@ -724,7 +761,7 @@ public:
if (Spell != Loc) if (Spell != Loc)
AddMacroUse(db, SM, usr, SymbolKind::Var, Spell); AddMacroUse(db, SM, usr, SymbolKind::Var, Spell);
if (var->def.detailed_name[0] == '\0') 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; QualType T;
if (auto *VD = dyn_cast<VarDecl>(D)) if (auto *VD = dyn_cast<VarDecl>(D))
T = VD->getType(); T = VD->getType();
@ -741,63 +778,44 @@ public:
Usr usr1 = static_cast<Usr>(BT->getKind()); Usr usr1 = static_cast<Usr>(BT->getKind());
var->def.type = usr1; var->def.type = usr1;
db->ToType(usr1).instances.push_back(usr); db->ToType(usr1).instances.push_back(usr);
} else { } else if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T))) {
for (const Decl *D1 = GetTypeDecl(T); D1; ) { if (isa<TemplateTypeParmDecl>(D1)) {
if (auto *R1 = dyn_cast<CXXRecordDecl>(D1)) { // e.g. TemplateTypeParmDecl is not handled by
if (auto *S1 = dyn_cast<ClassTemplateSpecializationDecl>(D1)) { // handleDeclOccurence.
if (!S1->getTypeAsWritten()) { SourceRange R1 = D1->getSourceRange();
llvm::PointerUnion<ClassTemplateDecl *, if (SM.getFileID(R1.getBegin()) == LocFID) {
ClassTemplatePartialSpecializationDecl *> IndexParam::DeclInfo *info1;
Result = S1->getSpecializedTemplateOrPartial(); Usr usr1 = GetUsr(D1, &info1);
if (Result.is<ClassTemplateDecl *>()) IndexType &type1 = db->ToType(usr1);
D1 = Result.get<ClassTemplateDecl *>(); SourceLocation L1 = D1->getLocation();
else type1.def.spell =
D1 = Result.get<ClassTemplatePartialSpecializationDecl *>(); GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC,
continue; Role::Definition);
} type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1),
} else if (auto *D2 = R1->getInstantiatedFromMemberClass()) { LexDC, Role::None);
D1 = D2; type1.def.detailed_name = Intern(info1->short_name);
continue; type1.def.short_name_size = int16_t(info1->short_name.size());
} type1.def.kind = lsSymbolKind::TypeParameter;
} else if (auto *TP1 = dyn_cast<TemplateTypeParmDecl>(D1)) { var->def.type = usr1;
// e.g. TemplateTypeParmDecl is not handled by type1.instances.push_back(usr);
// handleDeclOccurence. break;
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()) { } else if (!var->def.spell && var->declarations.empty()) {
// e.g. lambda parameter // e.g. lambda parameter
SourceLocation L = OrigD->getLocation(); SourceLocation L = D->getLocation();
if (SM.getFileID(L) == LocFID) { if (SM.getFileID(L) == LocFID) {
var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}), var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}),
SemDC, Role::Definition); SemDC, Role::Definition);
var->def.extent = var->def.extent =
GetUse(db, lid, FromTokenRange(SM, Lang, OrigD->getSourceRange()), GetUse(db, lid, FromTokenRange(SM, Lang, D->getSourceRange()),
LexDC, Role::None); LexDC, Role::None);
} }
} }
@ -807,8 +825,8 @@ public:
switch (D->getKind()) { switch (D->getKind()) {
case Decl::Namespace: case Decl::Namespace:
type->def.kind = lsSymbolKind::Namespace; type->def.kind = lsSymbolKind::Namespace;
if (OrigD->isFirstDecl()) { if (D->isFirstDecl()) {
auto *ND = cast<NamespaceDecl>(OrigD); auto *ND = cast<NamespaceDecl>(D);
auto *ND1 = cast<Decl>(ND->getParent()); auto *ND1 = cast<Decl>(ND->getParent());
if (isa<NamespaceDecl>(ND1)) { if (isa<NamespaceDecl>(ND1)) {
Usr usr1 = GetUsr(ND1); Usr usr1 = GetUsr(ND1);
@ -859,29 +877,19 @@ public:
break; break;
case Decl::CXXRecord: case Decl::CXXRecord:
if (is_def) { if (is_def) {
auto *RD = dyn_cast<CXXRecordDecl>(OrigD); auto *RD = dyn_cast<CXXRecordDecl>(D);
if (RD && RD->hasDefinition()) { if (RD && RD->hasDefinition())
for (const CXXBaseSpecifier &Base : RD->bases()) { for (const CXXBaseSpecifier &Base : RD->bases())
QualType T = Base.getType(); if (const Decl *BaseD =
const NamedDecl *BaseD = nullptr; GetAdjustedDecl(GetTypeDecl(Base.getType()))) {
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) {
Usr usr1 = GetUsr(BaseD); Usr usr1 = GetUsr(BaseD);
type->def.bases.push_back(usr1); type->def.bases.push_back(usr1);
db->ToType(usr1).derived.push_back(usr); db->ToType(usr1).derived.push_back(usr);
} }
}
}
} }
[[fallthrough]]; [[fallthrough]];
case Decl::Record: case Decl::Record:
if (auto *RD = dyn_cast<RecordDecl>(OrigD)) { if (auto *RD = dyn_cast<RecordDecl>(D)) {
// spec has no Union, use Class // spec has no Union, use Class
type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct
: lsSymbolKind::Class; : lsSymbolKind::Class;
@ -964,7 +972,7 @@ public:
if (auto *TD = dyn_cast<TypedefNameDecl>(D)) { if (auto *TD = dyn_cast<TypedefNameDecl>(D)) {
bool specialization = false; bool specialization = false;
QualType T = TD->getUnderlyingType(); QualType T = TD->getUnderlyingType();
if (const Decl *D1 = GetTypeDecl(T, &specialization)) { if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T, &specialization))) {
Usr usr1 = GetUsr(D1); Usr usr1 = GetUsr(D1);
IndexType &type1 = db->ToType(usr1); IndexType &type1 = db->ToType(usr1);
type->def.alias_of = usr1; type->def.alias_of = usr1;