blob: c7e487ab9ae6c1eb4d542825f8f1f02043c0edcb [file] [log] [blame]
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +00001//===- IndexingContext.cpp - Indexing context data ------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "IndexingContext.h"
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000010#include "clang/AST/ASTContext.h"
Reid Kleckner60573ae2019-11-15 17:31:55 -080011#include "clang/AST/Attr.h"
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000012#include "clang/AST/DeclObjC.h"
Reid Kleckner60573ae2019-11-15 17:31:55 -080013#include "clang/AST/DeclTemplate.h"
14#include "clang/Basic/SourceLocation.h"
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000015#include "clang/Basic/SourceManager.h"
Reid Kleckner60573ae2019-11-15 17:31:55 -080016#include "clang/Index/IndexDataConsumer.h"
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000017
18using namespace clang;
19using namespace index;
20
Argyrios Kyrtzidis6e5ca5b2017-04-21 05:42:46 +000021static bool isGeneratedDecl(const Decl *D) {
22 if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>()) {
23 return attr->getGeneratedDeclaration();
24 }
25 return false;
26}
27
28bool IndexingContext::shouldIndex(const Decl *D) {
29 return !isGeneratedDecl(D);
30}
31
Alex Lorenza352ba02017-04-24 14:04:58 +000032const LangOptions &IndexingContext::getLangOpts() const {
33 return Ctx->getLangOpts();
34}
35
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000036bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
37 return IndexOpts.IndexFunctionLocals;
38}
39
Fangrui Songd50f36e2018-07-09 21:49:06 +000040bool IndexingContext::shouldIndexImplicitInstantiation() const {
41 return IndexOpts.IndexImplicitInstantiation;
42}
43
Kadir Cetinkaya0468fc02019-02-11 13:02:21 +000044bool IndexingContext::shouldIndexParametersInDeclarations() const {
45 return IndexOpts.IndexParametersInDeclarations;
46}
47
Kadir Cetinkayab7805172019-02-21 09:52:33 +000048bool IndexingContext::shouldIndexTemplateParameters() const {
49 return IndexOpts.IndexTemplateParameters;
50}
51
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000052bool IndexingContext::handleDecl(const Decl *D,
53 SymbolRoleSet Roles,
54 ArrayRef<SymbolRelation> Relations) {
Argyrios Kyrtzidis74790482017-02-17 04:49:41 +000055 return handleDecl(D, D->getLocation(), Roles, Relations);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000056}
57
58bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
59 SymbolRoleSet Roles,
60 ArrayRef<SymbolRelation> Relations,
61 const DeclContext *DC) {
62 if (!DC)
63 DC = D->getDeclContext();
Argyrios Kyrtzidis74790482017-02-17 04:49:41 +000064
65 const Decl *OrigD = D;
66 if (isa<ObjCPropertyImplDecl>(D)) {
67 D = cast<ObjCPropertyImplDecl>(D)->getPropertyDecl();
68 }
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000069 return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
70 Roles, Relations,
Argyrios Kyrtzidis74790482017-02-17 04:49:41 +000071 nullptr, OrigD, DC);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000072}
73
74bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
75 const NamedDecl *Parent,
76 const DeclContext *DC,
77 SymbolRoleSet Roles,
78 ArrayRef<SymbolRelation> Relations,
79 const Expr *RefE,
80 const Decl *RefD) {
Argyrios Kyrtzidis6d1a15b22017-02-26 05:37:56 +000081 if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000082 return true;
83
Kadir Cetinkayab7805172019-02-21 09:52:33 +000084 if (!shouldIndexTemplateParameters() &&
85 (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
86 isa<TemplateTemplateParmDecl>(D))) {
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000087 return true;
Kadir Cetinkayab7805172019-02-21 09:52:33 +000088 }
Fangrui Song6907ce22018-07-30 19:24:48 +000089
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000090 return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
91 RefE, RefD, DC);
92}
93
Argyrios Kyrtzidis32e5d862018-09-18 15:02:56 +000094static void reportModuleReferences(const Module *Mod,
95 ArrayRef<SourceLocation> IdLocs,
96 const ImportDecl *ImportD,
97 IndexDataConsumer &DataConsumer) {
98 if (!Mod)
99 return;
100 reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
101 DataConsumer);
102 DataConsumer.handleModuleOccurence(ImportD, Mod,
103 (SymbolRoleSet)SymbolRole::Reference,
104 IdLocs.back());
105}
106
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000107bool IndexingContext::importedModule(const ImportDecl *ImportD) {
Argyrios Kyrtzidis32e5d862018-09-18 15:02:56 +0000108 if (ImportD->isInvalidDecl())
109 return true;
110
Argyrios Kyrtzidis113387e2016-02-29 07:56:07 +0000111 SourceLocation Loc;
112 auto IdLocs = ImportD->getIdentifierLocs();
113 if (!IdLocs.empty())
Argyrios Kyrtzidis32e5d862018-09-18 15:02:56 +0000114 Loc = IdLocs.back();
Argyrios Kyrtzidis113387e2016-02-29 07:56:07 +0000115 else
116 Loc = ImportD->getLocation();
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000117
Sam McCallcc026eb2018-04-09 14:12:51 +0000118 SourceManager &SM = Ctx->getSourceManager();
119 FileID FID = SM.getFileID(SM.getFileLoc(Loc));
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000120 if (FID.isInvalid())
121 return true;
122
123 bool Invalid = false;
124 const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
125 if (Invalid || !SEntry.isFile())
126 return true;
127
128 if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
129 switch (IndexOpts.SystemSymbolFilter) {
130 case IndexingOptions::SystemSymbolFilterKind::None:
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000131 return true;
Ben Langmuir6aed6b42016-07-14 18:51:55 +0000132 case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000133 case IndexingOptions::SystemSymbolFilterKind::All:
134 break;
135 }
136 }
137
Argyrios Kyrtzidis32e5d862018-09-18 15:02:56 +0000138 const Module *Mod = ImportD->getImportedModule();
139 if (!ImportD->isImplicit() && Mod->Parent && !IdLocs.empty()) {
140 reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
141 DataConsumer);
142 }
143
Ben Langmuir6aed6b42016-07-14 18:51:55 +0000144 SymbolRoleSet Roles = (unsigned)SymbolRole::Declaration;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000145 if (ImportD->isImplicit())
146 Roles |= (unsigned)SymbolRole::Implicit;
147
Argyrios Kyrtzidis32e5d862018-09-18 15:02:56 +0000148 return DataConsumer.handleModuleOccurence(ImportD, Mod, Roles, Loc);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000149}
150
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000151bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
152 TemplateSpecializationKind TKind = TSK_Undeclared;
153 if (const ClassTemplateSpecializationDecl *
154 SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
155 TKind = SD->getSpecializationKind();
Argyrios Kyrtzidis9d8ab722016-11-07 21:20:15 +0000156 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000157 TKind = FD->getTemplateSpecializationKind();
Argyrios Kyrtzidis9d8ab722016-11-07 21:20:15 +0000158 } else if (auto *VD = dyn_cast<VarDecl>(D)) {
159 TKind = VD->getTemplateSpecializationKind();
Alex Lorenz2109d432017-05-23 16:23:28 +0000160 } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
161 if (RD->getInstantiatedFromMemberClass())
162 TKind = RD->getTemplateSpecializationKind();
Alex Lorenz9d605202017-05-23 16:35:50 +0000163 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
164 if (ED->getInstantiatedFromMemberEnum())
165 TKind = ED->getTemplateSpecializationKind();
Alex Lorenz4bbce512017-05-23 16:47:01 +0000166 } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D) ||
167 isa<EnumConstantDecl>(D)) {
Alex Lorenz73e27a62017-05-23 16:25:06 +0000168 if (const auto *Parent = dyn_cast<Decl>(D->getDeclContext()))
169 return isTemplateImplicitInstantiation(Parent);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000170 }
171 switch (TKind) {
172 case TSK_Undeclared:
173 case TSK_ExplicitSpecialization:
174 return false;
175 case TSK_ImplicitInstantiation:
176 case TSK_ExplicitInstantiationDeclaration:
177 case TSK_ExplicitInstantiationDefinition:
178 return true;
179 }
Saleem Abdulrasool9b0ac332016-02-15 00:36:52 +0000180 llvm_unreachable("invalid TemplateSpecializationKind");
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000181}
182
183bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
184 if (isa<ObjCInterfaceDecl>(D))
185 return false;
186 if (isa<ObjCCategoryDecl>(D))
187 return false;
188 if (isa<ObjCIvarDecl>(D))
189 return false;
190 if (isa<ObjCMethodDecl>(D))
191 return false;
192 if (isa<ImportDecl>(D))
193 return false;
194 return true;
195}
196
Alex Lorenz73e27a62017-05-23 16:25:06 +0000197static const CXXRecordDecl *
198getDeclContextForTemplateInstationPattern(const Decl *D) {
199 if (const auto *CTSD =
200 dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
201 return CTSD->getTemplateInstantiationPattern();
202 else if (const auto *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext()))
203 return RD->getInstantiatedFromMemberClass();
204 return nullptr;
205}
206
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000207static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
208 if (const ClassTemplateSpecializationDecl *
209 SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
210 return SD->getTemplateInstantiationPattern();
Argyrios Kyrtzidis9d8ab722016-11-07 21:20:15 +0000211 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000212 return FD->getTemplateInstantiationPattern();
Argyrios Kyrtzidis9d8ab722016-11-07 21:20:15 +0000213 } else if (auto *VD = dyn_cast<VarDecl>(D)) {
214 return VD->getTemplateInstantiationPattern();
Alex Lorenz2109d432017-05-23 16:23:28 +0000215 } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
216 return RD->getInstantiatedFromMemberClass();
Alex Lorenz9d605202017-05-23 16:35:50 +0000217 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
218 return ED->getInstantiatedFromMemberEnum();
Alex Lorenzfcbae3a2017-05-23 16:27:42 +0000219 } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
220 const auto *ND = cast<NamedDecl>(D);
Alex Lorenz73e27a62017-05-23 16:25:06 +0000221 if (const CXXRecordDecl *Pattern =
Alex Lorenzfcbae3a2017-05-23 16:27:42 +0000222 getDeclContextForTemplateInstationPattern(ND)) {
223 for (const NamedDecl *BaseND : Pattern->lookup(ND->getDeclName())) {
224 if (BaseND->isImplicit())
Alex Lorenz048c8a92017-05-15 14:26:22 +0000225 continue;
Alex Lorenzfcbae3a2017-05-23 16:27:42 +0000226 if (BaseND->getKind() == ND->getKind())
227 return BaseND;
Alex Lorenz048c8a92017-05-15 14:26:22 +0000228 }
229 }
Alex Lorenz4bbce512017-05-23 16:47:01 +0000230 } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
231 if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
232 if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
233 for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
234 return BaseECD;
235 }
236 }
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000237 }
238 return nullptr;
239}
240
Argyrios Kyrtzidis66c49f72016-03-31 20:18:22 +0000241static bool isDeclADefinition(const Decl *D, const DeclContext *ContainerDC, ASTContext &Ctx) {
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000242 if (auto VD = dyn_cast<VarDecl>(D))
243 return VD->isThisDeclarationADefinition(Ctx);
244
245 if (auto FD = dyn_cast<FunctionDecl>(D))
246 return FD->isThisDeclarationADefinition();
247
248 if (auto TD = dyn_cast<TagDecl>(D))
249 return TD->isThisDeclarationADefinition();
250
251 if (auto MD = dyn_cast<ObjCMethodDecl>(D))
Argyrios Kyrtzidis66c49f72016-03-31 20:18:22 +0000252 return MD->isThisDeclarationADefinition() || isa<ObjCImplDecl>(ContainerDC);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000253
254 if (isa<TypedefNameDecl>(D) ||
255 isa<EnumConstantDecl>(D) ||
256 isa<FieldDecl>(D) ||
257 isa<MSPropertyDecl>(D) ||
258 isa<ObjCImplDecl>(D) ||
259 isa<ObjCPropertyImplDecl>(D))
260 return true;
261
262 return false;
263}
264
Ben Langmuirda467ed2017-07-12 22:05:30 +0000265/// Whether the given NamedDecl should be skipped because it has no name.
266static bool shouldSkipNamelessDecl(const NamedDecl *ND) {
Argyrios Kyrtzidis47827622017-08-15 17:20:37 +0000267 return (ND->getDeclName().isEmpty() && !isa<TagDecl>(ND) &&
268 !isa<ObjCCategoryDecl>(ND)) || isa<CXXDeductionGuideDecl>(ND);
Ben Langmuirda467ed2017-07-12 22:05:30 +0000269}
270
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000271static const Decl *adjustParent(const Decl *Parent) {
272 if (!Parent)
273 return nullptr;
274 for (;; Parent = cast<Decl>(Parent->getDeclContext())) {
275 if (isa<TranslationUnitDecl>(Parent))
276 return nullptr;
277 if (isa<LinkageSpecDecl>(Parent) || isa<BlockDecl>(Parent))
278 continue;
279 if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
280 if (NS->isAnonymousNamespace())
281 continue;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000282 } else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
283 if (RD->isAnonymousStructOrUnion())
284 continue;
Ben Langmuirda467ed2017-07-12 22:05:30 +0000285 } else if (auto ND = dyn_cast<NamedDecl>(Parent)) {
286 if (shouldSkipNamelessDecl(ND))
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000287 continue;
288 }
289 return Parent;
290 }
291}
292
293static const Decl *getCanonicalDecl(const Decl *D) {
294 D = D->getCanonicalDecl();
295 if (auto TD = dyn_cast<TemplateDecl>(D)) {
Krasimir Georgieve62dd8b2017-07-18 07:20:53 +0000296 if (auto TTD = TD->getTemplatedDecl()) {
297 D = TTD;
298 assert(D->isCanonicalDecl());
299 }
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000300 }
301
302 return D;
303}
304
Argyrios Kyrtzidisa9876ca2017-03-23 16:34:47 +0000305static bool shouldReportOccurrenceForSystemDeclOnlyMode(
306 bool IsRef, SymbolRoleSet Roles, ArrayRef<SymbolRelation> Relations) {
307 if (!IsRef)
308 return true;
309
310 auto acceptForRelation = [](SymbolRoleSet roles) -> bool {
311 bool accept = false;
312 applyForEachSymbolRoleInterruptible(roles, [&accept](SymbolRole r) -> bool {
313 switch (r) {
314 case SymbolRole::RelationChildOf:
315 case SymbolRole::RelationBaseOf:
316 case SymbolRole::RelationOverrideOf:
317 case SymbolRole::RelationExtendedBy:
318 case SymbolRole::RelationAccessorOf:
319 case SymbolRole::RelationIBTypeOf:
320 accept = true;
321 return false;
322 case SymbolRole::Declaration:
323 case SymbolRole::Definition:
324 case SymbolRole::Reference:
325 case SymbolRole::Read:
326 case SymbolRole::Write:
327 case SymbolRole::Call:
328 case SymbolRole::Dynamic:
329 case SymbolRole::AddressOf:
330 case SymbolRole::Implicit:
Eric Liu8c971952018-07-09 08:44:05 +0000331 case SymbolRole::Undefinition:
Argyrios Kyrtzidisa9876ca2017-03-23 16:34:47 +0000332 case SymbolRole::RelationReceivedBy:
333 case SymbolRole::RelationCalledBy:
334 case SymbolRole::RelationContainedBy:
Alex Lorenzf6071c32017-04-20 10:43:22 +0000335 case SymbolRole::RelationSpecializationOf:
Kadir Cetinkayae7eb27a2019-03-08 08:30:20 +0000336 case SymbolRole::NameReference:
Argyrios Kyrtzidisa9876ca2017-03-23 16:34:47 +0000337 return true;
338 }
Simon Pilgrimdfbf0492017-03-24 16:59:14 +0000339 llvm_unreachable("Unsupported SymbolRole value!");
Argyrios Kyrtzidisa9876ca2017-03-23 16:34:47 +0000340 });
341 return accept;
342 };
343
344 for (auto &Rel : Relations) {
345 if (acceptForRelation(Rel.Roles))
346 return true;
347 }
348
349 return false;
350}
351
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000352bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
353 bool IsRef, const Decl *Parent,
354 SymbolRoleSet Roles,
355 ArrayRef<SymbolRelation> Relations,
356 const Expr *OrigE,
357 const Decl *OrigD,
358 const DeclContext *ContainerDC) {
359 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
360 return true;
Ben Langmuirda467ed2017-07-12 22:05:30 +0000361 if (!isa<NamedDecl>(D) || shouldSkipNamelessDecl(cast<NamedDecl>(D)))
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000362 return true;
363
364 SourceManager &SM = Ctx->getSourceManager();
Sam McCallcc026eb2018-04-09 14:12:51 +0000365 FileID FID = SM.getFileID(SM.getFileLoc(Loc));
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000366 if (FID.isInvalid())
367 return true;
368
369 bool Invalid = false;
370 const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
371 if (Invalid || !SEntry.isFile())
372 return true;
373
374 if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
375 switch (IndexOpts.SystemSymbolFilter) {
376 case IndexingOptions::SystemSymbolFilterKind::None:
377 return true;
378 case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
Argyrios Kyrtzidisa9876ca2017-03-23 16:34:47 +0000379 if (!shouldReportOccurrenceForSystemDeclOnlyMode(IsRef, Roles, Relations))
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000380 return true;
381 break;
382 case IndexingOptions::SystemSymbolFilterKind::All:
383 break;
384 }
385 }
386
Eric Liu3e0051b2018-07-20 08:08:56 +0000387 if (!OrigD)
388 OrigD = D;
389
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000390 if (isTemplateImplicitInstantiation(D)) {
391 if (!IsRef)
392 return true;
393 D = adjustTemplateImplicitInstantiation(D);
394 if (!D)
395 return true;
396 assert(!isTemplateImplicitInstantiation(D));
397 }
398
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000399 if (IsRef)
400 Roles |= (unsigned)SymbolRole::Reference;
Argyrios Kyrtzidis74790482017-02-17 04:49:41 +0000401 else if (isDeclADefinition(OrigD, ContainerDC, *Ctx))
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000402 Roles |= (unsigned)SymbolRole::Definition;
403 else
404 Roles |= (unsigned)SymbolRole::Declaration;
405
406 D = getCanonicalDecl(D);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000407 Parent = adjustParent(Parent);
408 if (Parent)
409 Parent = getCanonicalDecl(Parent);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000410
411 SmallVector<SymbolRelation, 6> FinalRelations;
412 FinalRelations.reserve(Relations.size()+1);
413
414 auto addRelation = [&](SymbolRelation Rel) {
Fangrui Song75e74e02019-03-31 08:48:19 +0000415 auto It = llvm::find_if(FinalRelations, [&](SymbolRelation Elem) -> bool {
416 return Elem.RelatedSymbol == Rel.RelatedSymbol;
417 });
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000418 if (It != FinalRelations.end()) {
419 It->Roles |= Rel.Roles;
420 } else {
421 FinalRelations.push_back(Rel);
422 }
423 Roles |= Rel.Roles;
424 };
425
Argyrios Kyrtzidisdf60aa82017-01-11 20:51:10 +0000426 if (Parent) {
Argyrios Kyrtzidis6d1a15b22017-02-26 05:37:56 +0000427 if (IsRef || (!isa<ParmVarDecl>(D) && isFunctionLocalSymbol(D))) {
Argyrios Kyrtzidisde0f5082017-01-11 21:01:07 +0000428 addRelation(SymbolRelation{
429 (unsigned)SymbolRole::RelationContainedBy,
430 Parent
431 });
Argyrios Kyrtzidis6d1a15b22017-02-26 05:37:56 +0000432 } else {
Argyrios Kyrtzidisde0f5082017-01-11 21:01:07 +0000433 addRelation(SymbolRelation{
434 (unsigned)SymbolRole::RelationChildOf,
435 Parent
436 });
Argyrios Kyrtzidisdf60aa82017-01-11 20:51:10 +0000437 }
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000438 }
Argyrios Kyrtzidisdf60aa82017-01-11 20:51:10 +0000439
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000440 for (auto &Rel : Relations) {
441 addRelation(SymbolRelation(Rel.Roles,
442 Rel.RelatedSymbol->getCanonicalDecl()));
443 }
444
Sam McCallcc026eb2018-04-09 14:12:51 +0000445 IndexDataConsumer::ASTNodeInfo Node{OrigE, OrigD, Parent, ContainerDC};
446 return DataConsumer.handleDeclOccurence(D, Roles, FinalRelations, Loc, Node);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000447}
Eric Liu8c971952018-07-09 08:44:05 +0000448
449void IndexingContext::handleMacroDefined(const IdentifierInfo &Name,
450 SourceLocation Loc,
451 const MacroInfo &MI) {
452 SymbolRoleSet Roles = (unsigned)SymbolRole::Definition;
453 DataConsumer.handleMacroOccurence(&Name, &MI, Roles, Loc);
454}
455
456void IndexingContext::handleMacroUndefined(const IdentifierInfo &Name,
457 SourceLocation Loc,
458 const MacroInfo &MI) {
459 SymbolRoleSet Roles = (unsigned)SymbolRole::Undefinition;
460 DataConsumer.handleMacroOccurence(&Name, &MI, Roles, Loc);
461}
462
463void IndexingContext::handleMacroReference(const IdentifierInfo &Name,
464 SourceLocation Loc,
465 const MacroInfo &MI) {
466 SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
467 DataConsumer.handleMacroOccurence(&Name, &MI, Roles, Loc);
468}