annotate clang/lib/Index/IndexingContext.cpp @ 176:de4ac79aef9d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 17:13:11 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- IndexingContext.cpp - Indexing context data ------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "IndexingContext.h"
anatofuz
parents:
diff changeset
10 #include "clang/AST/ASTContext.h"
anatofuz
parents:
diff changeset
11 #include "clang/AST/Attr.h"
anatofuz
parents:
diff changeset
12 #include "clang/AST/DeclObjC.h"
anatofuz
parents:
diff changeset
13 #include "clang/AST/DeclTemplate.h"
anatofuz
parents:
diff changeset
14 #include "clang/Basic/SourceLocation.h"
anatofuz
parents:
diff changeset
15 #include "clang/Basic/SourceManager.h"
anatofuz
parents:
diff changeset
16 #include "clang/Index/IndexDataConsumer.h"
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 using namespace clang;
anatofuz
parents:
diff changeset
19 using namespace index;
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 static bool isGeneratedDecl(const Decl *D) {
anatofuz
parents:
diff changeset
22 if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>()) {
anatofuz
parents:
diff changeset
23 return attr->getGeneratedDeclaration();
anatofuz
parents:
diff changeset
24 }
anatofuz
parents:
diff changeset
25 return false;
anatofuz
parents:
diff changeset
26 }
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 bool IndexingContext::shouldIndex(const Decl *D) {
anatofuz
parents:
diff changeset
29 return !isGeneratedDecl(D);
anatofuz
parents:
diff changeset
30 }
anatofuz
parents:
diff changeset
31
anatofuz
parents:
diff changeset
32 const LangOptions &IndexingContext::getLangOpts() const {
anatofuz
parents:
diff changeset
33 return Ctx->getLangOpts();
anatofuz
parents:
diff changeset
34 }
anatofuz
parents:
diff changeset
35
anatofuz
parents:
diff changeset
36 bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
anatofuz
parents:
diff changeset
37 return IndexOpts.IndexFunctionLocals;
anatofuz
parents:
diff changeset
38 }
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 bool IndexingContext::shouldIndexImplicitInstantiation() const {
anatofuz
parents:
diff changeset
41 return IndexOpts.IndexImplicitInstantiation;
anatofuz
parents:
diff changeset
42 }
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 bool IndexingContext::shouldIndexParametersInDeclarations() const {
anatofuz
parents:
diff changeset
45 return IndexOpts.IndexParametersInDeclarations;
anatofuz
parents:
diff changeset
46 }
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 bool IndexingContext::shouldIndexTemplateParameters() const {
anatofuz
parents:
diff changeset
49 return IndexOpts.IndexTemplateParameters;
anatofuz
parents:
diff changeset
50 }
anatofuz
parents:
diff changeset
51
anatofuz
parents:
diff changeset
52 bool IndexingContext::handleDecl(const Decl *D,
anatofuz
parents:
diff changeset
53 SymbolRoleSet Roles,
anatofuz
parents:
diff changeset
54 ArrayRef<SymbolRelation> Relations) {
anatofuz
parents:
diff changeset
55 return handleDecl(D, D->getLocation(), Roles, Relations);
anatofuz
parents:
diff changeset
56 }
anatofuz
parents:
diff changeset
57
anatofuz
parents:
diff changeset
58 bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
anatofuz
parents:
diff changeset
59 SymbolRoleSet Roles,
anatofuz
parents:
diff changeset
60 ArrayRef<SymbolRelation> Relations,
anatofuz
parents:
diff changeset
61 const DeclContext *DC) {
anatofuz
parents:
diff changeset
62 if (!DC)
anatofuz
parents:
diff changeset
63 DC = D->getDeclContext();
anatofuz
parents:
diff changeset
64
anatofuz
parents:
diff changeset
65 const Decl *OrigD = D;
anatofuz
parents:
diff changeset
66 if (isa<ObjCPropertyImplDecl>(D)) {
anatofuz
parents:
diff changeset
67 D = cast<ObjCPropertyImplDecl>(D)->getPropertyDecl();
anatofuz
parents:
diff changeset
68 }
anatofuz
parents:
diff changeset
69 return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
anatofuz
parents:
diff changeset
70 Roles, Relations,
anatofuz
parents:
diff changeset
71 nullptr, OrigD, DC);
anatofuz
parents:
diff changeset
72 }
anatofuz
parents:
diff changeset
73
anatofuz
parents:
diff changeset
74 bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
anatofuz
parents:
diff changeset
75 const NamedDecl *Parent,
anatofuz
parents:
diff changeset
76 const DeclContext *DC,
anatofuz
parents:
diff changeset
77 SymbolRoleSet Roles,
anatofuz
parents:
diff changeset
78 ArrayRef<SymbolRelation> Relations,
anatofuz
parents:
diff changeset
79 const Expr *RefE,
anatofuz
parents:
diff changeset
80 const Decl *RefD) {
anatofuz
parents:
diff changeset
81 if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
anatofuz
parents:
diff changeset
82 return true;
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 if (!shouldIndexTemplateParameters() &&
anatofuz
parents:
diff changeset
85 (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
anatofuz
parents:
diff changeset
86 isa<TemplateTemplateParmDecl>(D))) {
anatofuz
parents:
diff changeset
87 return true;
anatofuz
parents:
diff changeset
88 }
anatofuz
parents:
diff changeset
89
anatofuz
parents:
diff changeset
90 return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
anatofuz
parents:
diff changeset
91 RefE, RefD, DC);
anatofuz
parents:
diff changeset
92 }
anatofuz
parents:
diff changeset
93
anatofuz
parents:
diff changeset
94 static void reportModuleReferences(const Module *Mod,
anatofuz
parents:
diff changeset
95 ArrayRef<SourceLocation> IdLocs,
anatofuz
parents:
diff changeset
96 const ImportDecl *ImportD,
anatofuz
parents:
diff changeset
97 IndexDataConsumer &DataConsumer) {
anatofuz
parents:
diff changeset
98 if (!Mod)
anatofuz
parents:
diff changeset
99 return;
anatofuz
parents:
diff changeset
100 reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
anatofuz
parents:
diff changeset
101 DataConsumer);
anatofuz
parents:
diff changeset
102 DataConsumer.handleModuleOccurrence(
anatofuz
parents:
diff changeset
103 ImportD, Mod, (SymbolRoleSet)SymbolRole::Reference, IdLocs.back());
anatofuz
parents:
diff changeset
104 }
anatofuz
parents:
diff changeset
105
anatofuz
parents:
diff changeset
106 bool IndexingContext::importedModule(const ImportDecl *ImportD) {
anatofuz
parents:
diff changeset
107 if (ImportD->isInvalidDecl())
anatofuz
parents:
diff changeset
108 return true;
anatofuz
parents:
diff changeset
109
anatofuz
parents:
diff changeset
110 SourceLocation Loc;
anatofuz
parents:
diff changeset
111 auto IdLocs = ImportD->getIdentifierLocs();
anatofuz
parents:
diff changeset
112 if (!IdLocs.empty())
anatofuz
parents:
diff changeset
113 Loc = IdLocs.back();
anatofuz
parents:
diff changeset
114 else
anatofuz
parents:
diff changeset
115 Loc = ImportD->getLocation();
anatofuz
parents:
diff changeset
116
anatofuz
parents:
diff changeset
117 SourceManager &SM = Ctx->getSourceManager();
anatofuz
parents:
diff changeset
118 FileID FID = SM.getFileID(SM.getFileLoc(Loc));
anatofuz
parents:
diff changeset
119 if (FID.isInvalid())
anatofuz
parents:
diff changeset
120 return true;
anatofuz
parents:
diff changeset
121
anatofuz
parents:
diff changeset
122 bool Invalid = false;
anatofuz
parents:
diff changeset
123 const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
anatofuz
parents:
diff changeset
124 if (Invalid || !SEntry.isFile())
anatofuz
parents:
diff changeset
125 return true;
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
anatofuz
parents:
diff changeset
128 switch (IndexOpts.SystemSymbolFilter) {
anatofuz
parents:
diff changeset
129 case IndexingOptions::SystemSymbolFilterKind::None:
anatofuz
parents:
diff changeset
130 return true;
anatofuz
parents:
diff changeset
131 case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
anatofuz
parents:
diff changeset
132 case IndexingOptions::SystemSymbolFilterKind::All:
anatofuz
parents:
diff changeset
133 break;
anatofuz
parents:
diff changeset
134 }
anatofuz
parents:
diff changeset
135 }
anatofuz
parents:
diff changeset
136
anatofuz
parents:
diff changeset
137 const Module *Mod = ImportD->getImportedModule();
anatofuz
parents:
diff changeset
138 if (!ImportD->isImplicit() && Mod->Parent && !IdLocs.empty()) {
anatofuz
parents:
diff changeset
139 reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
anatofuz
parents:
diff changeset
140 DataConsumer);
anatofuz
parents:
diff changeset
141 }
anatofuz
parents:
diff changeset
142
anatofuz
parents:
diff changeset
143 SymbolRoleSet Roles = (unsigned)SymbolRole::Declaration;
anatofuz
parents:
diff changeset
144 if (ImportD->isImplicit())
anatofuz
parents:
diff changeset
145 Roles |= (unsigned)SymbolRole::Implicit;
anatofuz
parents:
diff changeset
146
anatofuz
parents:
diff changeset
147 return DataConsumer.handleModuleOccurrence(ImportD, Mod, Roles, Loc);
anatofuz
parents:
diff changeset
148 }
anatofuz
parents:
diff changeset
149
anatofuz
parents:
diff changeset
150 bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
anatofuz
parents:
diff changeset
151 TemplateSpecializationKind TKind = TSK_Undeclared;
anatofuz
parents:
diff changeset
152 if (const ClassTemplateSpecializationDecl *
anatofuz
parents:
diff changeset
153 SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
anatofuz
parents:
diff changeset
154 TKind = SD->getSpecializationKind();
anatofuz
parents:
diff changeset
155 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
anatofuz
parents:
diff changeset
156 TKind = FD->getTemplateSpecializationKind();
anatofuz
parents:
diff changeset
157 } else if (auto *VD = dyn_cast<VarDecl>(D)) {
anatofuz
parents:
diff changeset
158 TKind = VD->getTemplateSpecializationKind();
anatofuz
parents:
diff changeset
159 } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
anatofuz
parents:
diff changeset
160 if (RD->getInstantiatedFromMemberClass())
anatofuz
parents:
diff changeset
161 TKind = RD->getTemplateSpecializationKind();
anatofuz
parents:
diff changeset
162 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
anatofuz
parents:
diff changeset
163 if (ED->getInstantiatedFromMemberEnum())
anatofuz
parents:
diff changeset
164 TKind = ED->getTemplateSpecializationKind();
anatofuz
parents:
diff changeset
165 } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D) ||
anatofuz
parents:
diff changeset
166 isa<EnumConstantDecl>(D)) {
anatofuz
parents:
diff changeset
167 if (const auto *Parent = dyn_cast<Decl>(D->getDeclContext()))
anatofuz
parents:
diff changeset
168 return isTemplateImplicitInstantiation(Parent);
anatofuz
parents:
diff changeset
169 }
anatofuz
parents:
diff changeset
170 switch (TKind) {
anatofuz
parents:
diff changeset
171 case TSK_Undeclared:
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
172 // Instantiation maybe not happen yet when we see a SpecializationDecl,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
173 // e.g. when the type doesn't need to be complete, we still treat it as an
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
174 // instantiation as we'd like to keep the canonicalized result consistent.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
175 return isa<ClassTemplateSpecializationDecl>(D);
150
anatofuz
parents:
diff changeset
176 case TSK_ExplicitSpecialization:
anatofuz
parents:
diff changeset
177 return false;
anatofuz
parents:
diff changeset
178 case TSK_ImplicitInstantiation:
anatofuz
parents:
diff changeset
179 case TSK_ExplicitInstantiationDeclaration:
anatofuz
parents:
diff changeset
180 case TSK_ExplicitInstantiationDefinition:
anatofuz
parents:
diff changeset
181 return true;
anatofuz
parents:
diff changeset
182 }
anatofuz
parents:
diff changeset
183 llvm_unreachable("invalid TemplateSpecializationKind");
anatofuz
parents:
diff changeset
184 }
anatofuz
parents:
diff changeset
185
anatofuz
parents:
diff changeset
186 bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
anatofuz
parents:
diff changeset
187 if (isa<ObjCInterfaceDecl>(D))
anatofuz
parents:
diff changeset
188 return false;
anatofuz
parents:
diff changeset
189 if (isa<ObjCCategoryDecl>(D))
anatofuz
parents:
diff changeset
190 return false;
anatofuz
parents:
diff changeset
191 if (isa<ObjCIvarDecl>(D))
anatofuz
parents:
diff changeset
192 return false;
anatofuz
parents:
diff changeset
193 if (isa<ObjCMethodDecl>(D))
anatofuz
parents:
diff changeset
194 return false;
anatofuz
parents:
diff changeset
195 if (isa<ImportDecl>(D))
anatofuz
parents:
diff changeset
196 return false;
anatofuz
parents:
diff changeset
197 return true;
anatofuz
parents:
diff changeset
198 }
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 static const CXXRecordDecl *
anatofuz
parents:
diff changeset
201 getDeclContextForTemplateInstationPattern(const Decl *D) {
anatofuz
parents:
diff changeset
202 if (const auto *CTSD =
anatofuz
parents:
diff changeset
203 dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
anatofuz
parents:
diff changeset
204 return CTSD->getTemplateInstantiationPattern();
anatofuz
parents:
diff changeset
205 else if (const auto *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext()))
anatofuz
parents:
diff changeset
206 return RD->getInstantiatedFromMemberClass();
anatofuz
parents:
diff changeset
207 return nullptr;
anatofuz
parents:
diff changeset
208 }
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
anatofuz
parents:
diff changeset
211 if (const ClassTemplateSpecializationDecl *
anatofuz
parents:
diff changeset
212 SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
213 const auto *Template = SD->getTemplateInstantiationPattern();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
214 if (Template)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
215 return Template;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
216 // Fallback to primary template if no instantiation is available yet (e.g.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
217 // the type doesn't need to be complete).
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
218 return SD->getSpecializedTemplate()->getTemplatedDecl();
150
anatofuz
parents:
diff changeset
219 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
anatofuz
parents:
diff changeset
220 return FD->getTemplateInstantiationPattern();
anatofuz
parents:
diff changeset
221 } else if (auto *VD = dyn_cast<VarDecl>(D)) {
anatofuz
parents:
diff changeset
222 return VD->getTemplateInstantiationPattern();
anatofuz
parents:
diff changeset
223 } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
anatofuz
parents:
diff changeset
224 return RD->getInstantiatedFromMemberClass();
anatofuz
parents:
diff changeset
225 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
anatofuz
parents:
diff changeset
226 return ED->getInstantiatedFromMemberEnum();
anatofuz
parents:
diff changeset
227 } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
anatofuz
parents:
diff changeset
228 const auto *ND = cast<NamedDecl>(D);
anatofuz
parents:
diff changeset
229 if (const CXXRecordDecl *Pattern =
anatofuz
parents:
diff changeset
230 getDeclContextForTemplateInstationPattern(ND)) {
anatofuz
parents:
diff changeset
231 for (const NamedDecl *BaseND : Pattern->lookup(ND->getDeclName())) {
anatofuz
parents:
diff changeset
232 if (BaseND->isImplicit())
anatofuz
parents:
diff changeset
233 continue;
anatofuz
parents:
diff changeset
234 if (BaseND->getKind() == ND->getKind())
anatofuz
parents:
diff changeset
235 return BaseND;
anatofuz
parents:
diff changeset
236 }
anatofuz
parents:
diff changeset
237 }
anatofuz
parents:
diff changeset
238 } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
anatofuz
parents:
diff changeset
239 if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
anatofuz
parents:
diff changeset
240 if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
anatofuz
parents:
diff changeset
241 for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
anatofuz
parents:
diff changeset
242 return BaseECD;
anatofuz
parents:
diff changeset
243 }
anatofuz
parents:
diff changeset
244 }
anatofuz
parents:
diff changeset
245 }
anatofuz
parents:
diff changeset
246 return nullptr;
anatofuz
parents:
diff changeset
247 }
anatofuz
parents:
diff changeset
248
anatofuz
parents:
diff changeset
249 static bool isDeclADefinition(const Decl *D, const DeclContext *ContainerDC, ASTContext &Ctx) {
anatofuz
parents:
diff changeset
250 if (auto VD = dyn_cast<VarDecl>(D))
anatofuz
parents:
diff changeset
251 return VD->isThisDeclarationADefinition(Ctx);
anatofuz
parents:
diff changeset
252
anatofuz
parents:
diff changeset
253 if (auto FD = dyn_cast<FunctionDecl>(D))
anatofuz
parents:
diff changeset
254 return FD->isThisDeclarationADefinition();
anatofuz
parents:
diff changeset
255
anatofuz
parents:
diff changeset
256 if (auto TD = dyn_cast<TagDecl>(D))
anatofuz
parents:
diff changeset
257 return TD->isThisDeclarationADefinition();
anatofuz
parents:
diff changeset
258
anatofuz
parents:
diff changeset
259 if (auto MD = dyn_cast<ObjCMethodDecl>(D))
anatofuz
parents:
diff changeset
260 return MD->isThisDeclarationADefinition() || isa<ObjCImplDecl>(ContainerDC);
anatofuz
parents:
diff changeset
261
anatofuz
parents:
diff changeset
262 if (isa<TypedefNameDecl>(D) ||
anatofuz
parents:
diff changeset
263 isa<EnumConstantDecl>(D) ||
anatofuz
parents:
diff changeset
264 isa<FieldDecl>(D) ||
anatofuz
parents:
diff changeset
265 isa<MSPropertyDecl>(D) ||
anatofuz
parents:
diff changeset
266 isa<ObjCImplDecl>(D) ||
anatofuz
parents:
diff changeset
267 isa<ObjCPropertyImplDecl>(D))
anatofuz
parents:
diff changeset
268 return true;
anatofuz
parents:
diff changeset
269
anatofuz
parents:
diff changeset
270 return false;
anatofuz
parents:
diff changeset
271 }
anatofuz
parents:
diff changeset
272
anatofuz
parents:
diff changeset
273 /// Whether the given NamedDecl should be skipped because it has no name.
anatofuz
parents:
diff changeset
274 static bool shouldSkipNamelessDecl(const NamedDecl *ND) {
anatofuz
parents:
diff changeset
275 return (ND->getDeclName().isEmpty() && !isa<TagDecl>(ND) &&
anatofuz
parents:
diff changeset
276 !isa<ObjCCategoryDecl>(ND)) || isa<CXXDeductionGuideDecl>(ND);
anatofuz
parents:
diff changeset
277 }
anatofuz
parents:
diff changeset
278
anatofuz
parents:
diff changeset
279 static const Decl *adjustParent(const Decl *Parent) {
anatofuz
parents:
diff changeset
280 if (!Parent)
anatofuz
parents:
diff changeset
281 return nullptr;
anatofuz
parents:
diff changeset
282 for (;; Parent = cast<Decl>(Parent->getDeclContext())) {
anatofuz
parents:
diff changeset
283 if (isa<TranslationUnitDecl>(Parent))
anatofuz
parents:
diff changeset
284 return nullptr;
anatofuz
parents:
diff changeset
285 if (isa<LinkageSpecDecl>(Parent) || isa<BlockDecl>(Parent))
anatofuz
parents:
diff changeset
286 continue;
anatofuz
parents:
diff changeset
287 if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
anatofuz
parents:
diff changeset
288 if (NS->isAnonymousNamespace())
anatofuz
parents:
diff changeset
289 continue;
anatofuz
parents:
diff changeset
290 } else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
anatofuz
parents:
diff changeset
291 if (RD->isAnonymousStructOrUnion())
anatofuz
parents:
diff changeset
292 continue;
anatofuz
parents:
diff changeset
293 } else if (auto ND = dyn_cast<NamedDecl>(Parent)) {
anatofuz
parents:
diff changeset
294 if (shouldSkipNamelessDecl(ND))
anatofuz
parents:
diff changeset
295 continue;
anatofuz
parents:
diff changeset
296 }
anatofuz
parents:
diff changeset
297 return Parent;
anatofuz
parents:
diff changeset
298 }
anatofuz
parents:
diff changeset
299 }
anatofuz
parents:
diff changeset
300
anatofuz
parents:
diff changeset
301 static const Decl *getCanonicalDecl(const Decl *D) {
anatofuz
parents:
diff changeset
302 D = D->getCanonicalDecl();
anatofuz
parents:
diff changeset
303 if (auto TD = dyn_cast<TemplateDecl>(D)) {
anatofuz
parents:
diff changeset
304 if (auto TTD = TD->getTemplatedDecl()) {
anatofuz
parents:
diff changeset
305 D = TTD;
anatofuz
parents:
diff changeset
306 assert(D->isCanonicalDecl());
anatofuz
parents:
diff changeset
307 }
anatofuz
parents:
diff changeset
308 }
anatofuz
parents:
diff changeset
309
anatofuz
parents:
diff changeset
310 return D;
anatofuz
parents:
diff changeset
311 }
anatofuz
parents:
diff changeset
312
anatofuz
parents:
diff changeset
313 static bool shouldReportOccurrenceForSystemDeclOnlyMode(
anatofuz
parents:
diff changeset
314 bool IsRef, SymbolRoleSet Roles, ArrayRef<SymbolRelation> Relations) {
anatofuz
parents:
diff changeset
315 if (!IsRef)
anatofuz
parents:
diff changeset
316 return true;
anatofuz
parents:
diff changeset
317
anatofuz
parents:
diff changeset
318 auto acceptForRelation = [](SymbolRoleSet roles) -> bool {
anatofuz
parents:
diff changeset
319 bool accept = false;
anatofuz
parents:
diff changeset
320 applyForEachSymbolRoleInterruptible(roles, [&accept](SymbolRole r) -> bool {
anatofuz
parents:
diff changeset
321 switch (r) {
anatofuz
parents:
diff changeset
322 case SymbolRole::RelationChildOf:
anatofuz
parents:
diff changeset
323 case SymbolRole::RelationBaseOf:
anatofuz
parents:
diff changeset
324 case SymbolRole::RelationOverrideOf:
anatofuz
parents:
diff changeset
325 case SymbolRole::RelationExtendedBy:
anatofuz
parents:
diff changeset
326 case SymbolRole::RelationAccessorOf:
anatofuz
parents:
diff changeset
327 case SymbolRole::RelationIBTypeOf:
anatofuz
parents:
diff changeset
328 accept = true;
anatofuz
parents:
diff changeset
329 return false;
anatofuz
parents:
diff changeset
330 case SymbolRole::Declaration:
anatofuz
parents:
diff changeset
331 case SymbolRole::Definition:
anatofuz
parents:
diff changeset
332 case SymbolRole::Reference:
anatofuz
parents:
diff changeset
333 case SymbolRole::Read:
anatofuz
parents:
diff changeset
334 case SymbolRole::Write:
anatofuz
parents:
diff changeset
335 case SymbolRole::Call:
anatofuz
parents:
diff changeset
336 case SymbolRole::Dynamic:
anatofuz
parents:
diff changeset
337 case SymbolRole::AddressOf:
anatofuz
parents:
diff changeset
338 case SymbolRole::Implicit:
anatofuz
parents:
diff changeset
339 case SymbolRole::Undefinition:
anatofuz
parents:
diff changeset
340 case SymbolRole::RelationReceivedBy:
anatofuz
parents:
diff changeset
341 case SymbolRole::RelationCalledBy:
anatofuz
parents:
diff changeset
342 case SymbolRole::RelationContainedBy:
anatofuz
parents:
diff changeset
343 case SymbolRole::RelationSpecializationOf:
anatofuz
parents:
diff changeset
344 case SymbolRole::NameReference:
anatofuz
parents:
diff changeset
345 return true;
anatofuz
parents:
diff changeset
346 }
anatofuz
parents:
diff changeset
347 llvm_unreachable("Unsupported SymbolRole value!");
anatofuz
parents:
diff changeset
348 });
anatofuz
parents:
diff changeset
349 return accept;
anatofuz
parents:
diff changeset
350 };
anatofuz
parents:
diff changeset
351
anatofuz
parents:
diff changeset
352 for (auto &Rel : Relations) {
anatofuz
parents:
diff changeset
353 if (acceptForRelation(Rel.Roles))
anatofuz
parents:
diff changeset
354 return true;
anatofuz
parents:
diff changeset
355 }
anatofuz
parents:
diff changeset
356
anatofuz
parents:
diff changeset
357 return false;
anatofuz
parents:
diff changeset
358 }
anatofuz
parents:
diff changeset
359
anatofuz
parents:
diff changeset
360 bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
anatofuz
parents:
diff changeset
361 bool IsRef, const Decl *Parent,
anatofuz
parents:
diff changeset
362 SymbolRoleSet Roles,
anatofuz
parents:
diff changeset
363 ArrayRef<SymbolRelation> Relations,
anatofuz
parents:
diff changeset
364 const Expr *OrigE,
anatofuz
parents:
diff changeset
365 const Decl *OrigD,
anatofuz
parents:
diff changeset
366 const DeclContext *ContainerDC) {
anatofuz
parents:
diff changeset
367 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
anatofuz
parents:
diff changeset
368 return true;
anatofuz
parents:
diff changeset
369 if (!isa<NamedDecl>(D) || shouldSkipNamelessDecl(cast<NamedDecl>(D)))
anatofuz
parents:
diff changeset
370 return true;
anatofuz
parents:
diff changeset
371
anatofuz
parents:
diff changeset
372 SourceManager &SM = Ctx->getSourceManager();
anatofuz
parents:
diff changeset
373 FileID FID = SM.getFileID(SM.getFileLoc(Loc));
anatofuz
parents:
diff changeset
374 if (FID.isInvalid())
anatofuz
parents:
diff changeset
375 return true;
anatofuz
parents:
diff changeset
376
anatofuz
parents:
diff changeset
377 bool Invalid = false;
anatofuz
parents:
diff changeset
378 const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
anatofuz
parents:
diff changeset
379 if (Invalid || !SEntry.isFile())
anatofuz
parents:
diff changeset
380 return true;
anatofuz
parents:
diff changeset
381
anatofuz
parents:
diff changeset
382 if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
anatofuz
parents:
diff changeset
383 switch (IndexOpts.SystemSymbolFilter) {
anatofuz
parents:
diff changeset
384 case IndexingOptions::SystemSymbolFilterKind::None:
anatofuz
parents:
diff changeset
385 return true;
anatofuz
parents:
diff changeset
386 case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
anatofuz
parents:
diff changeset
387 if (!shouldReportOccurrenceForSystemDeclOnlyMode(IsRef, Roles, Relations))
anatofuz
parents:
diff changeset
388 return true;
anatofuz
parents:
diff changeset
389 break;
anatofuz
parents:
diff changeset
390 case IndexingOptions::SystemSymbolFilterKind::All:
anatofuz
parents:
diff changeset
391 break;
anatofuz
parents:
diff changeset
392 }
anatofuz
parents:
diff changeset
393 }
anatofuz
parents:
diff changeset
394
anatofuz
parents:
diff changeset
395 if (!OrigD)
anatofuz
parents:
diff changeset
396 OrigD = D;
anatofuz
parents:
diff changeset
397
anatofuz
parents:
diff changeset
398 if (isTemplateImplicitInstantiation(D)) {
anatofuz
parents:
diff changeset
399 if (!IsRef)
anatofuz
parents:
diff changeset
400 return true;
anatofuz
parents:
diff changeset
401 D = adjustTemplateImplicitInstantiation(D);
anatofuz
parents:
diff changeset
402 if (!D)
anatofuz
parents:
diff changeset
403 return true;
anatofuz
parents:
diff changeset
404 assert(!isTemplateImplicitInstantiation(D));
anatofuz
parents:
diff changeset
405 }
anatofuz
parents:
diff changeset
406
anatofuz
parents:
diff changeset
407 if (IsRef)
anatofuz
parents:
diff changeset
408 Roles |= (unsigned)SymbolRole::Reference;
anatofuz
parents:
diff changeset
409 else if (isDeclADefinition(OrigD, ContainerDC, *Ctx))
anatofuz
parents:
diff changeset
410 Roles |= (unsigned)SymbolRole::Definition;
anatofuz
parents:
diff changeset
411 else
anatofuz
parents:
diff changeset
412 Roles |= (unsigned)SymbolRole::Declaration;
anatofuz
parents:
diff changeset
413
anatofuz
parents:
diff changeset
414 D = getCanonicalDecl(D);
anatofuz
parents:
diff changeset
415 Parent = adjustParent(Parent);
anatofuz
parents:
diff changeset
416 if (Parent)
anatofuz
parents:
diff changeset
417 Parent = getCanonicalDecl(Parent);
anatofuz
parents:
diff changeset
418
anatofuz
parents:
diff changeset
419 SmallVector<SymbolRelation, 6> FinalRelations;
anatofuz
parents:
diff changeset
420 FinalRelations.reserve(Relations.size()+1);
anatofuz
parents:
diff changeset
421
anatofuz
parents:
diff changeset
422 auto addRelation = [&](SymbolRelation Rel) {
anatofuz
parents:
diff changeset
423 auto It = llvm::find_if(FinalRelations, [&](SymbolRelation Elem) -> bool {
anatofuz
parents:
diff changeset
424 return Elem.RelatedSymbol == Rel.RelatedSymbol;
anatofuz
parents:
diff changeset
425 });
anatofuz
parents:
diff changeset
426 if (It != FinalRelations.end()) {
anatofuz
parents:
diff changeset
427 It->Roles |= Rel.Roles;
anatofuz
parents:
diff changeset
428 } else {
anatofuz
parents:
diff changeset
429 FinalRelations.push_back(Rel);
anatofuz
parents:
diff changeset
430 }
anatofuz
parents:
diff changeset
431 Roles |= Rel.Roles;
anatofuz
parents:
diff changeset
432 };
anatofuz
parents:
diff changeset
433
anatofuz
parents:
diff changeset
434 if (Parent) {
anatofuz
parents:
diff changeset
435 if (IsRef || (!isa<ParmVarDecl>(D) && isFunctionLocalSymbol(D))) {
anatofuz
parents:
diff changeset
436 addRelation(SymbolRelation{
anatofuz
parents:
diff changeset
437 (unsigned)SymbolRole::RelationContainedBy,
anatofuz
parents:
diff changeset
438 Parent
anatofuz
parents:
diff changeset
439 });
anatofuz
parents:
diff changeset
440 } else {
anatofuz
parents:
diff changeset
441 addRelation(SymbolRelation{
anatofuz
parents:
diff changeset
442 (unsigned)SymbolRole::RelationChildOf,
anatofuz
parents:
diff changeset
443 Parent
anatofuz
parents:
diff changeset
444 });
anatofuz
parents:
diff changeset
445 }
anatofuz
parents:
diff changeset
446 }
anatofuz
parents:
diff changeset
447
anatofuz
parents:
diff changeset
448 for (auto &Rel : Relations) {
anatofuz
parents:
diff changeset
449 addRelation(SymbolRelation(Rel.Roles,
anatofuz
parents:
diff changeset
450 Rel.RelatedSymbol->getCanonicalDecl()));
anatofuz
parents:
diff changeset
451 }
anatofuz
parents:
diff changeset
452
anatofuz
parents:
diff changeset
453 IndexDataConsumer::ASTNodeInfo Node{OrigE, OrigD, Parent, ContainerDC};
anatofuz
parents:
diff changeset
454 return DataConsumer.handleDeclOccurrence(D, Roles, FinalRelations, Loc, Node);
anatofuz
parents:
diff changeset
455 }
anatofuz
parents:
diff changeset
456
anatofuz
parents:
diff changeset
457 void IndexingContext::handleMacroDefined(const IdentifierInfo &Name,
anatofuz
parents:
diff changeset
458 SourceLocation Loc,
anatofuz
parents:
diff changeset
459 const MacroInfo &MI) {
anatofuz
parents:
diff changeset
460 SymbolRoleSet Roles = (unsigned)SymbolRole::Definition;
anatofuz
parents:
diff changeset
461 DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
anatofuz
parents:
diff changeset
462 }
anatofuz
parents:
diff changeset
463
anatofuz
parents:
diff changeset
464 void IndexingContext::handleMacroUndefined(const IdentifierInfo &Name,
anatofuz
parents:
diff changeset
465 SourceLocation Loc,
anatofuz
parents:
diff changeset
466 const MacroInfo &MI) {
anatofuz
parents:
diff changeset
467 SymbolRoleSet Roles = (unsigned)SymbolRole::Undefinition;
anatofuz
parents:
diff changeset
468 DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
anatofuz
parents:
diff changeset
469 }
anatofuz
parents:
diff changeset
470
anatofuz
parents:
diff changeset
471 void IndexingContext::handleMacroReference(const IdentifierInfo &Name,
anatofuz
parents:
diff changeset
472 SourceLocation Loc,
anatofuz
parents:
diff changeset
473 const MacroInfo &MI) {
anatofuz
parents:
diff changeset
474 SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
anatofuz
parents:
diff changeset
475 DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
anatofuz
parents:
diff changeset
476 }