[clang][extract-api][NFC] Use dedicated API to check for macro equality
[llvm-project.git] / clang / lib / Index / IndexBody.cpp
blobfa35f749d028470c81e876f9857e46b68489a99b
1 //===- IndexBody.cpp - Indexing statements --------------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "IndexingContext.h"
10 #include "clang/AST/RecursiveASTVisitor.h"
11 #include "clang/AST/ASTLambda.h"
13 using namespace clang;
14 using namespace clang::index;
16 namespace {
18 class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
19 IndexingContext &IndexCtx;
20 const NamedDecl *Parent;
21 const DeclContext *ParentDC;
22 SmallVector<Stmt*, 16> StmtStack;
24 typedef RecursiveASTVisitor<BodyIndexer> base;
26 Stmt *getParentStmt() const {
27 return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2];
29 public:
30 BodyIndexer(IndexingContext &indexCtx,
31 const NamedDecl *Parent, const DeclContext *DC)
32 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
34 bool shouldWalkTypesOfTypeLocs() const { return false; }
36 bool dataTraverseStmtPre(Stmt *S) {
37 StmtStack.push_back(S);
38 return true;
41 bool dataTraverseStmtPost(Stmt *S) {
42 assert(StmtStack.back() == S);
43 StmtStack.pop_back();
44 return true;
47 bool TraverseTypeLoc(TypeLoc TL) {
48 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
49 return true;
52 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
53 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
54 return true;
57 SymbolRoleSet getRolesForRef(const Expr *E,
58 SmallVectorImpl<SymbolRelation> &Relations) {
59 SymbolRoleSet Roles{};
60 assert(!StmtStack.empty() && E == StmtStack.back());
61 if (StmtStack.size() == 1)
62 return Roles;
63 auto It = StmtStack.end()-2;
64 while (isa<CastExpr>(*It) || isa<ParenExpr>(*It)) {
65 if (auto ICE = dyn_cast<ImplicitCastExpr>(*It)) {
66 if (ICE->getCastKind() == CK_LValueToRValue)
67 Roles |= (unsigned)(unsigned)SymbolRole::Read;
69 if (It == StmtStack.begin())
70 break;
71 --It;
73 const Stmt *Parent = *It;
75 if (auto BO = dyn_cast<BinaryOperator>(Parent)) {
76 if (BO->getOpcode() == BO_Assign && BO->getLHS()->IgnoreParenCasts() == E)
77 Roles |= (unsigned)SymbolRole::Write;
79 } else if (auto UO = dyn_cast<UnaryOperator>(Parent)) {
80 if (UO->isIncrementDecrementOp()) {
81 Roles |= (unsigned)SymbolRole::Read;
82 Roles |= (unsigned)SymbolRole::Write;
83 } else if (UO->getOpcode() == UO_AddrOf) {
84 Roles |= (unsigned)SymbolRole::AddressOf;
87 } else if (auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
88 if (CA->getLHS()->IgnoreParenCasts() == E) {
89 Roles |= (unsigned)SymbolRole::Read;
90 Roles |= (unsigned)SymbolRole::Write;
93 } else if (auto CE = dyn_cast<CallExpr>(Parent)) {
94 if (CE->getCallee()->IgnoreParenCasts() == E) {
95 addCallRole(Roles, Relations);
96 if (auto *ME = dyn_cast<MemberExpr>(E)) {
97 if (auto *CXXMD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
98 if (CXXMD->isVirtual() && !ME->hasQualifier()) {
99 Roles |= (unsigned)SymbolRole::Dynamic;
100 auto BaseTy = ME->getBase()->IgnoreImpCasts()->getType();
101 if (!BaseTy.isNull())
102 if (auto *CXXRD = BaseTy->getPointeeCXXRecordDecl())
103 Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
104 CXXRD);
107 } else if (auto CXXOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
108 if (CXXOp->getNumArgs() > 0 && CXXOp->getArg(0)->IgnoreParenCasts() == E) {
109 OverloadedOperatorKind Op = CXXOp->getOperator();
110 if (Op == OO_Equal) {
111 Roles |= (unsigned)SymbolRole::Write;
112 } else if ((Op >= OO_PlusEqual && Op <= OO_PipeEqual) ||
113 Op == OO_LessLessEqual || Op == OO_GreaterGreaterEqual ||
114 Op == OO_PlusPlus || Op == OO_MinusMinus) {
115 Roles |= (unsigned)SymbolRole::Read;
116 Roles |= (unsigned)SymbolRole::Write;
117 } else if (Op == OO_Amp) {
118 Roles |= (unsigned)SymbolRole::AddressOf;
124 return Roles;
127 void addCallRole(SymbolRoleSet &Roles,
128 SmallVectorImpl<SymbolRelation> &Relations) {
129 Roles |= (unsigned)SymbolRole::Call;
130 if (auto *FD = dyn_cast<FunctionDecl>(ParentDC))
131 Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, FD);
132 else if (auto *MD = dyn_cast<ObjCMethodDecl>(ParentDC))
133 Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, MD);
136 bool VisitDeclRefExpr(DeclRefExpr *E) {
137 SmallVector<SymbolRelation, 4> Relations;
138 SymbolRoleSet Roles = getRolesForRef(E, Relations);
139 return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
140 Parent, ParentDC, Roles, Relations, E);
143 bool VisitMemberExpr(MemberExpr *E) {
144 SourceLocation Loc = E->getMemberLoc();
145 if (Loc.isInvalid())
146 Loc = E->getBeginLoc();
147 SmallVector<SymbolRelation, 4> Relations;
148 SymbolRoleSet Roles = getRolesForRef(E, Relations);
149 return IndexCtx.handleReference(E->getMemberDecl(), Loc,
150 Parent, ParentDC, Roles, Relations, E);
153 bool indexDependentReference(
154 const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
155 llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
156 if (!T)
157 return true;
158 const TemplateSpecializationType *TST =
159 T->getAs<TemplateSpecializationType>();
160 if (!TST)
161 return true;
162 TemplateName TN = TST->getTemplateName();
163 const ClassTemplateDecl *TD =
164 dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
165 if (!TD)
166 return true;
167 CXXRecordDecl *RD = TD->getTemplatedDecl();
168 if (!RD->hasDefinition())
169 return true;
170 RD = RD->getDefinition();
171 std::vector<const NamedDecl *> Symbols =
172 RD->lookupDependentName(NameInfo.getName(), Filter);
173 // FIXME: Improve overload handling.
174 if (Symbols.size() != 1)
175 return true;
176 SourceLocation Loc = NameInfo.getLoc();
177 if (Loc.isInvalid())
178 Loc = E->getBeginLoc();
179 SmallVector<SymbolRelation, 4> Relations;
180 SymbolRoleSet Roles = getRolesForRef(E, Relations);
181 return IndexCtx.handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
182 Relations, E);
185 bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
186 const DeclarationNameInfo &Info = E->getMemberNameInfo();
187 return indexDependentReference(
188 E, E->getBaseType().getTypePtrOrNull(), Info,
189 [](const NamedDecl *D) { return D->isCXXInstanceMember(); });
192 bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
193 const DeclarationNameInfo &Info = E->getNameInfo();
194 const NestedNameSpecifier *NNS = E->getQualifier();
195 return indexDependentReference(
196 E, NNS->getAsType(), Info,
197 [](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
200 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
201 for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
202 if (D.isFieldDesignator() && D.getField())
203 return IndexCtx.handleReference(D.getField(), D.getFieldLoc(), Parent,
204 ParentDC, SymbolRoleSet(), {}, E);
206 return true;
209 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
210 SmallVector<SymbolRelation, 4> Relations;
211 SymbolRoleSet Roles = getRolesForRef(E, Relations);
212 return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
213 Parent, ParentDC, Roles, Relations, E);
216 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
217 auto isDynamic = [](const ObjCMessageExpr *MsgE)->bool {
218 if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
219 return false;
220 if (auto *RecE = dyn_cast<ObjCMessageExpr>(
221 MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
222 if (RecE->getMethodFamily() == OMF_alloc)
223 return false;
225 return true;
228 if (ObjCMethodDecl *MD = E->getMethodDecl()) {
229 SymbolRoleSet Roles{};
230 SmallVector<SymbolRelation, 2> Relations;
231 addCallRole(Roles, Relations);
232 Stmt *Containing = getParentStmt();
234 auto IsImplicitProperty = [](const PseudoObjectExpr *POE) -> bool {
235 const auto *E = POE->getSyntacticForm();
236 if (const auto *BinOp = dyn_cast<BinaryOperator>(E))
237 E = BinOp->getLHS();
238 const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E);
239 if (!PRE)
240 return false;
241 if (PRE->isExplicitProperty())
242 return false;
243 if (const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
244 // Class properties that are explicitly defined using @property
245 // declarations are represented implicitly as there is no ivar for
246 // class properties.
247 if (Getter->isClassMethod() &&
248 Getter->getCanonicalDecl()->findPropertyDecl())
249 return false;
251 return true;
253 bool IsPropCall = Containing && isa<PseudoObjectExpr>(Containing);
254 // Implicit property message sends are not 'implicit'.
255 if ((E->isImplicit() || IsPropCall) &&
256 !(IsPropCall &&
257 IsImplicitProperty(cast<PseudoObjectExpr>(Containing))))
258 Roles |= (unsigned)SymbolRole::Implicit;
260 if (isDynamic(E)) {
261 Roles |= (unsigned)SymbolRole::Dynamic;
263 auto addReceivers = [&](const ObjCObjectType *Ty) {
264 if (!Ty)
265 return;
266 if (const auto *clsD = Ty->getInterface()) {
267 Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
268 clsD);
270 for (const auto *protD : Ty->quals()) {
271 Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
272 protD);
275 QualType recT = E->getReceiverType();
276 if (const auto *Ptr = recT->getAs<ObjCObjectPointerType>())
277 addReceivers(Ptr->getObjectType());
278 else
279 addReceivers(recT->getAs<ObjCObjectType>());
282 return IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
283 Parent, ParentDC, Roles, Relations, E);
285 return true;
288 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
289 if (E->isExplicitProperty()) {
290 SmallVector<SymbolRelation, 2> Relations;
291 SymbolRoleSet Roles = getRolesForRef(E, Relations);
292 return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
293 Parent, ParentDC, Roles, Relations, E);
294 } else if (const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter()) {
295 // Class properties that are explicitly defined using @property
296 // declarations are represented implicitly as there is no ivar for class
297 // properties.
298 if (Getter->isClassMethod()) {
299 if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
300 SmallVector<SymbolRelation, 2> Relations;
301 SymbolRoleSet Roles = getRolesForRef(E, Relations);
302 return IndexCtx.handleReference(PD, E->getLocation(), Parent,
303 ParentDC, Roles, Relations, E);
308 // No need to do a handleReference for the objc method, because there will
309 // be a message expr as part of PseudoObjectExpr.
310 return true;
313 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
314 return IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(),
315 Parent, ParentDC, SymbolRoleSet(), {}, E);
318 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
319 return IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
320 Parent, ParentDC, SymbolRoleSet(), {}, E);
323 bool passObjCLiteralMethodCall(const ObjCMethodDecl *MD, const Expr *E) {
324 SymbolRoleSet Roles{};
325 SmallVector<SymbolRelation, 2> Relations;
326 addCallRole(Roles, Relations);
327 Roles |= (unsigned)SymbolRole::Implicit;
328 return IndexCtx.handleReference(MD, E->getBeginLoc(), Parent, ParentDC,
329 Roles, Relations, E);
332 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
333 if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
334 return passObjCLiteralMethodCall(MD, E);
336 return true;
339 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
340 if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) {
341 return passObjCLiteralMethodCall(MD, E);
343 return true;
346 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
347 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) {
348 return passObjCLiteralMethodCall(MD, E);
350 return true;
353 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
354 SymbolRoleSet Roles{};
355 SmallVector<SymbolRelation, 2> Relations;
356 addCallRole(Roles, Relations);
357 return IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
358 Parent, ParentDC, Roles, Relations, E);
361 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
362 DataRecursionQueue *Q = nullptr) {
363 if (E->getOperatorLoc().isInvalid())
364 return true; // implicit.
365 return base::TraverseCXXOperatorCallExpr(E, Q);
368 bool VisitDeclStmt(DeclStmt *S) {
369 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
370 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
371 return true;
374 DeclGroupRef DG = S->getDeclGroup();
375 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
376 const Decl *D = *I;
377 if (!D)
378 continue;
379 if (!isFunctionLocalSymbol(D))
380 IndexCtx.indexTopLevelDecl(D);
383 return true;
386 bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
387 Expr *Init) {
388 if (C->capturesThis() || C->capturesVLAType())
389 return true;
391 if (!base::TraverseStmt(Init))
392 return false;
394 if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
395 return IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(),
396 Parent, ParentDC, SymbolRoleSet());
398 return true;
401 // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating
402 // the things that we visit. Make sure to only visit the semantic form.
403 // Also visit things that are in the syntactic form but not the semantic one,
404 // for example the indices in DesignatedInitExprs.
405 bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {
406 auto visitForm = [&](InitListExpr *Form) {
407 for (Stmt *SubStmt : Form->children()) {
408 if (!TraverseStmt(SubStmt, Q))
409 return false;
411 return true;
414 auto visitSyntacticDesignatedInitExpr = [&](DesignatedInitExpr *E) -> bool {
415 for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
416 if (D.isFieldDesignator() && D.getField())
417 return IndexCtx.handleReference(D.getField(), D.getFieldLoc(),
418 Parent, ParentDC, SymbolRoleSet(),
419 {}, E);
421 return true;
424 InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
425 InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
427 if (SemaForm) {
428 // Visit things present in syntactic form but not the semantic form.
429 if (SyntaxForm) {
430 for (Expr *init : SyntaxForm->inits()) {
431 if (auto *DIE = dyn_cast<DesignatedInitExpr>(init))
432 visitSyntacticDesignatedInitExpr(DIE);
435 return visitForm(SemaForm);
438 // No semantic, try the syntactic.
439 if (SyntaxForm) {
440 return visitForm(SyntaxForm);
443 return true;
446 bool VisitOffsetOfExpr(OffsetOfExpr *S) {
447 for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
448 const OffsetOfNode &Component = S->getComponent(I);
449 if (Component.getKind() == OffsetOfNode::Field)
450 IndexCtx.handleReference(Component.getField(), Component.getEndLoc(),
451 Parent, ParentDC, SymbolRoleSet(), {});
452 // FIXME: Try to resolve dependent field references.
454 return true;
457 bool VisitParmVarDecl(ParmVarDecl* D) {
458 // Index the parameters of lambda expression.
459 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
460 const auto *DC = D->getDeclContext();
461 if (DC && isLambdaCallOperator(DC))
462 IndexCtx.handleDecl(D);
464 return true;
467 bool VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
468 SmallVector<SymbolRelation, 4> Relations;
469 SymbolRoleSet Roles = getRolesForRef(E, Relations);
470 for (auto *D : E->decls())
471 IndexCtx.handleReference(D, E->getNameLoc(), Parent, ParentDC, Roles,
472 Relations, E);
473 return true;
477 } // anonymous namespace
479 void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
480 const DeclContext *DC) {
481 if (!S)
482 return;
484 if (!DC)
485 DC = Parent->getLexicalDeclContext();
486 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));