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 35cba6d49c
commit 5b7758a6ca
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"]
}, {
"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,

View File

@ -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,

View File

@ -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,

View File

@ -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": []
}

View File

@ -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,

View File

@ -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,

View File

@ -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": [],

View File

@ -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;