clang 17.0.0git
IndexBody.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
8
9#include "IndexingContext.h"
11#include "clang/AST/ASTLambda.h"
12#include "clang/AST/DeclCXX.h"
15#include "clang/AST/Type.h"
16
17using namespace clang;
18using namespace clang::index;
19
20namespace {
21
22class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
23 IndexingContext &IndexCtx;
24 const NamedDecl *Parent;
25 const DeclContext *ParentDC;
26 SmallVector<Stmt*, 16> StmtStack;
27
29
30 Stmt *getParentStmt() const {
31 return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2];
32 }
33public:
34 BodyIndexer(IndexingContext &indexCtx,
35 const NamedDecl *Parent, const DeclContext *DC)
36 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
37
38 bool shouldWalkTypesOfTypeLocs() const { return false; }
39
40 bool dataTraverseStmtPre(Stmt *S) {
41 StmtStack.push_back(S);
42 return true;
43 }
44
45 bool dataTraverseStmtPost(Stmt *S) {
46 assert(StmtStack.back() == S);
47 StmtStack.pop_back();
48 return true;
49 }
50
51 bool TraverseTypeLoc(TypeLoc TL) {
52 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
53 return true;
54 }
55
57 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
58 return true;
59 }
60
61 SymbolRoleSet getRolesForRef(const Expr *E,
63 SymbolRoleSet Roles{};
64 assert(!StmtStack.empty() && E == StmtStack.back());
65 if (StmtStack.size() == 1)
66 return Roles;
67 auto It = StmtStack.end()-2;
68 while (isa<CastExpr>(*It) || isa<ParenExpr>(*It)) {
69 if (auto ICE = dyn_cast<ImplicitCastExpr>(*It)) {
70 if (ICE->getCastKind() == CK_LValueToRValue)
71 Roles |= (unsigned)(unsigned)SymbolRole::Read;
72 }
73 if (It == StmtStack.begin())
74 break;
75 --It;
76 }
77 const Stmt *Parent = *It;
78
79 if (auto BO = dyn_cast<BinaryOperator>(Parent)) {
80 if (BO->getOpcode() == BO_Assign && BO->getLHS()->IgnoreParenCasts() == E)
81 Roles |= (unsigned)SymbolRole::Write;
82
83 } else if (auto UO = dyn_cast<UnaryOperator>(Parent)) {
84 if (UO->isIncrementDecrementOp()) {
85 Roles |= (unsigned)SymbolRole::Read;
86 Roles |= (unsigned)SymbolRole::Write;
87 } else if (UO->getOpcode() == UO_AddrOf) {
88 Roles |= (unsigned)SymbolRole::AddressOf;
89 }
90
91 } else if (auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
92 if (CA->getLHS()->IgnoreParenCasts() == E) {
93 Roles |= (unsigned)SymbolRole::Read;
94 Roles |= (unsigned)SymbolRole::Write;
95 }
96
97 } else if (auto CE = dyn_cast<CallExpr>(Parent)) {
98 if (CE->getCallee()->IgnoreParenCasts() == E) {
99 addCallRole(Roles, Relations);
100 if (auto *ME = dyn_cast<MemberExpr>(E)) {
101 if (auto *CXXMD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
102 if (CXXMD->isVirtual() && !ME->hasQualifier()) {
103 Roles |= (unsigned)SymbolRole::Dynamic;
104 auto BaseTy = ME->getBase()->IgnoreImpCasts()->getType();
105 if (!BaseTy.isNull())
106 if (auto *CXXRD = BaseTy->getPointeeCXXRecordDecl())
107 Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
108 CXXRD);
109 }
110 }
111 } else if (auto CXXOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
112 if (CXXOp->getNumArgs() > 0 && CXXOp->getArg(0)->IgnoreParenCasts() == E) {
113 OverloadedOperatorKind Op = CXXOp->getOperator();
114 if (Op == OO_Equal) {
115 Roles |= (unsigned)SymbolRole::Write;
116 } else if ((Op >= OO_PlusEqual && Op <= OO_PipeEqual) ||
117 Op == OO_LessLessEqual || Op == OO_GreaterGreaterEqual ||
118 Op == OO_PlusPlus || Op == OO_MinusMinus) {
119 Roles |= (unsigned)SymbolRole::Read;
120 Roles |= (unsigned)SymbolRole::Write;
121 } else if (Op == OO_Amp) {
122 Roles |= (unsigned)SymbolRole::AddressOf;
123 }
124 }
125 }
126 }
127
128 return Roles;
129 }
130
131 void addCallRole(SymbolRoleSet &Roles,
133 Roles |= (unsigned)SymbolRole::Call;
134 if (auto *FD = dyn_cast<FunctionDecl>(ParentDC))
135 Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, FD);
136 else if (auto *MD = dyn_cast<ObjCMethodDecl>(ParentDC))
137 Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, MD);
138 }
139
140 bool VisitDeclRefExpr(DeclRefExpr *E) {
142 SymbolRoleSet Roles = getRolesForRef(E, Relations);
143 return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
144 Parent, ParentDC, Roles, Relations, E);
145 }
146
147 bool VisitMemberExpr(MemberExpr *E) {
148 SourceLocation Loc = E->getMemberLoc();
149 if (Loc.isInvalid())
150 Loc = E->getBeginLoc();
152 SymbolRoleSet Roles = getRolesForRef(E, Relations);
153 return IndexCtx.handleReference(E->getMemberDecl(), Loc,
154 Parent, ParentDC, Roles, Relations, E);
155 }
156
157 bool indexDependentReference(
158 const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
159 llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
160 if (!T)
161 return true;
162 const TemplateSpecializationType *TST =
164 if (!TST)
165 return true;
166 TemplateName TN = TST->getTemplateName();
167 const ClassTemplateDecl *TD =
168 dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
169 if (!TD)
170 return true;
172 if (!RD->hasDefinition())
173 return true;
174 RD = RD->getDefinition();
175 std::vector<const NamedDecl *> Symbols =
176 RD->lookupDependentName(NameInfo.getName(), Filter);
177 // FIXME: Improve overload handling.
178 if (Symbols.size() != 1)
179 return true;
180 SourceLocation Loc = NameInfo.getLoc();
181 if (Loc.isInvalid())
182 Loc = E->getBeginLoc();
184 SymbolRoleSet Roles = getRolesForRef(E, Relations);
185 return IndexCtx.handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
186 Relations, E);
187 }
188
189 bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
190 const DeclarationNameInfo &Info = E->getMemberNameInfo();
191 return indexDependentReference(
192 E, E->getBaseType().getTypePtrOrNull(), Info,
193 [](const NamedDecl *D) { return D->isCXXInstanceMember(); });
194 }
195
196 bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
197 const DeclarationNameInfo &Info = E->getNameInfo();
198 const NestedNameSpecifier *NNS = E->getQualifier();
199 return indexDependentReference(
200 E, NNS->getAsType(), Info,
201 [](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
202 }
203
204 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
205 for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
206 if (D.isFieldDesignator() && D.getField())
207 return IndexCtx.handleReference(D.getField(), D.getFieldLoc(), Parent,
208 ParentDC, SymbolRoleSet(), {}, E);
209 }
210 return true;
211 }
212
213 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
215 SymbolRoleSet Roles = getRolesForRef(E, Relations);
216 return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
217 Parent, ParentDC, Roles, Relations, E);
218 }
219
220 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
221 auto isDynamic = [](const ObjCMessageExpr *MsgE)->bool {
222 if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
223 return false;
224 if (auto *RecE = dyn_cast<ObjCMessageExpr>(
225 MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
226 if (RecE->getMethodFamily() == OMF_alloc)
227 return false;
228 }
229 return true;
230 };
231
232 if (ObjCMethodDecl *MD = E->getMethodDecl()) {
233 SymbolRoleSet Roles{};
235 addCallRole(Roles, Relations);
236 Stmt *Containing = getParentStmt();
237
238 auto IsImplicitProperty = [](const PseudoObjectExpr *POE) -> bool {
239 const auto *E = POE->getSyntacticForm();
240 if (const auto *BinOp = dyn_cast<BinaryOperator>(E))
241 E = BinOp->getLHS();
242 const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E);
243 if (!PRE)
244 return false;
245 if (PRE->isExplicitProperty())
246 return false;
247 if (const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
248 // Class properties that are explicitly defined using @property
249 // declarations are represented implicitly as there is no ivar for
250 // class properties.
251 if (Getter->isClassMethod() &&
252 Getter->getCanonicalDecl()->findPropertyDecl())
253 return false;
254 }
255 return true;
256 };
257 bool IsPropCall = Containing && isa<PseudoObjectExpr>(Containing);
258 // Implicit property message sends are not 'implicit'.
259 if ((E->isImplicit() || IsPropCall) &&
260 !(IsPropCall &&
261 IsImplicitProperty(cast<PseudoObjectExpr>(Containing))))
262 Roles |= (unsigned)SymbolRole::Implicit;
263
264 if (isDynamic(E)) {
265 Roles |= (unsigned)SymbolRole::Dynamic;
266
267 auto addReceivers = [&](const ObjCObjectType *Ty) {
268 if (!Ty)
269 return;
270 if (const auto *clsD = Ty->getInterface()) {
271 Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
272 clsD);
273 }
274 for (const auto *protD : Ty->quals()) {
275 Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
276 protD);
277 }
278 };
279 QualType recT = E->getReceiverType();
280 if (const auto *Ptr = recT->getAs<ObjCObjectPointerType>())
281 addReceivers(Ptr->getObjectType());
282 else
283 addReceivers(recT->getAs<ObjCObjectType>());
284 }
285
286 return IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
287 Parent, ParentDC, Roles, Relations, E);
288 }
289 return true;
290 }
291
292 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
293 if (E->isExplicitProperty()) {
295 SymbolRoleSet Roles = getRolesForRef(E, Relations);
296 return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
297 Parent, ParentDC, Roles, Relations, E);
298 } else if (const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter()) {
299 // Class properties that are explicitly defined using @property
300 // declarations are represented implicitly as there is no ivar for class
301 // properties.
302 if (Getter->isClassMethod()) {
303 if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
305 SymbolRoleSet Roles = getRolesForRef(E, Relations);
306 return IndexCtx.handleReference(PD, E->getLocation(), Parent,
307 ParentDC, Roles, Relations, E);
308 }
309 }
310 }
311
312 // No need to do a handleReference for the objc method, because there will
313 // be a message expr as part of PseudoObjectExpr.
314 return true;
315 }
316
317 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
318 return IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(),
319 Parent, ParentDC, SymbolRoleSet(), {}, E);
320 }
321
322 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
323 return IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
324 Parent, ParentDC, SymbolRoleSet(), {}, E);
325 }
326
327 bool passObjCLiteralMethodCall(const ObjCMethodDecl *MD, const Expr *E) {
328 SymbolRoleSet Roles{};
330 addCallRole(Roles, Relations);
331 Roles |= (unsigned)SymbolRole::Implicit;
332 return IndexCtx.handleReference(MD, E->getBeginLoc(), Parent, ParentDC,
333 Roles, Relations, E);
334 }
335
336 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
337 if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
338 return passObjCLiteralMethodCall(MD, E);
339 }
340 return true;
341 }
342
343 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
345 return passObjCLiteralMethodCall(MD, E);
346 }
347 return true;
348 }
349
350 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
352 return passObjCLiteralMethodCall(MD, E);
353 }
354 return true;
355 }
356
357 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
358 SymbolRoleSet Roles{};
360 addCallRole(Roles, Relations);
361 return IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
362 Parent, ParentDC, Roles, Relations, E);
363 }
364
365 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
366 DataRecursionQueue *Q = nullptr) {
367 if (E->getOperatorLoc().isInvalid())
368 return true; // implicit.
369 return base::TraverseCXXOperatorCallExpr(E, Q);
370 }
371
372 bool VisitDeclStmt(DeclStmt *S) {
373 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
374 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
375 return true;
376 }
377
378 DeclGroupRef DG = S->getDeclGroup();
379 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
380 const Decl *D = *I;
381 if (!D)
382 continue;
383 if (!isFunctionLocalSymbol(D))
384 IndexCtx.indexTopLevelDecl(D);
385 }
386
387 return true;
388 }
389
391 Expr *Init) {
392 if (C->capturesThis() || C->capturesVLAType())
393 return true;
394
395 if (!base::TraverseStmt(Init))
396 return false;
397
398 if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
399 return IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(),
400 Parent, ParentDC, SymbolRoleSet());
401
402 return true;
403 }
404
405 // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating
406 // the things that we visit. Make sure to only visit the semantic form.
407 // Also visit things that are in the syntactic form but not the semantic one,
408 // for example the indices in DesignatedInitExprs.
409 bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {
410 auto visitForm = [&](InitListExpr *Form) {
411 for (Stmt *SubStmt : Form->children()) {
412 if (!TraverseStmt(SubStmt, Q))
413 return false;
414 }
415 return true;
416 };
417
418 auto visitSyntacticDesignatedInitExpr = [&](DesignatedInitExpr *E) -> bool {
419 for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
420 if (D.isFieldDesignator() && D.getField())
421 return IndexCtx.handleReference(D.getField(), D.getFieldLoc(),
422 Parent, ParentDC, SymbolRoleSet(),
423 {}, E);
424 }
425 return true;
426 };
427
428 InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
429 InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
430
431 if (SemaForm) {
432 // Visit things present in syntactic form but not the semantic form.
433 if (SyntaxForm) {
434 for (Expr *init : SyntaxForm->inits()) {
435 if (auto *DIE = dyn_cast<DesignatedInitExpr>(init))
436 visitSyntacticDesignatedInitExpr(DIE);
437 }
438 }
439 return visitForm(SemaForm);
440 }
441
442 // No semantic, try the syntactic.
443 if (SyntaxForm) {
444 return visitForm(SyntaxForm);
445 }
446
447 return true;
448 }
449
450 bool VisitOffsetOfExpr(OffsetOfExpr *S) {
451 for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
452 const OffsetOfNode &Component = S->getComponent(I);
453 if (Component.getKind() == OffsetOfNode::Field)
454 IndexCtx.handleReference(Component.getField(), Component.getEndLoc(),
455 Parent, ParentDC, SymbolRoleSet(), {});
456 // FIXME: Try to resolve dependent field references.
457 }
458 return true;
459 }
460
461 bool VisitParmVarDecl(ParmVarDecl* D) {
462 // Index the parameters of lambda expression and requires expression.
463 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
464 const auto *DC = D->getDeclContext();
465 if (DC && (isLambdaCallOperator(DC) || isa<RequiresExprBodyDecl>(DC)))
466 IndexCtx.handleDecl(D);
467 }
468 return true;
469 }
470
471 bool VisitOverloadExpr(OverloadExpr *E) {
473 SymbolRoleSet Roles = getRolesForRef(E, Relations);
474 for (auto *D : E->decls())
475 IndexCtx.handleReference(D, E->getNameLoc(), Parent, ParentDC, Roles,
476 Relations, E);
477 return true;
478 }
479
480 bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *R) {
482 Parent, ParentDC);
483 return true;
484 }
485
487 IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(),
488 Parent, ParentDC);
490 }
491};
492
493} // anonymous namespace
494
496 const DeclContext *DC) {
497 if (!S)
498 return;
499
500 if (!DC)
501 DC = Parent->getLexicalDeclContext();
502 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
503}
This file provides AST data structures related to concepts.
NodeId Parent
Definition: ASTDiff.cpp:191
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines Expressions and AST nodes for C++2a concepts.
C Language Family Type Representation.
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1518
SourceLocation getLocation() const
Definition: ExprCXX.h:1592
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1590
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition: ExprCXX.h:3627
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the name of the member that this expression refers to.
Definition: ExprCXX.h:3764
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:81
SourceLocation getOperatorLoc() const
Returns the location of the operator symbol in the expression.
Definition: ExprCXX.h:149
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
CXXRecordDecl * getDefinition() const
Definition: DeclCXX.h:548
bool hasDefinition() const
Definition: DeclCXX.h:555
std::vector< const NamedDecl * > lookupDependentName(DeclarationName Name, llvm::function_ref< bool(const NamedDecl *ND)> Filter)
Performs an imprecise lookup of a dependent name in this class.
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
SourceLocation getConceptNameLoc() const
Definition: ASTConcept.h:155
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:165
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:41
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1393
iterator begin()
Definition: DeclGroup.h:99
iterator end()
Definition: DeclGroup.h:105
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1238
ValueDecl * getDecl()
Definition: Expr.h:1306
SourceLocation getLocation() const
Definition: Expr.h:1314
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1311
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
DeclContext * getDeclContext()
Definition: DeclBase.h:441
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3269
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition: ExprCXX.h:3321
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
Definition: ExprCXX.h:3305
Represents a single C99 designator.
Definition: Expr.h:5111
Represents a C99 designated initializer expression.
Definition: Expr.h:5038
llvm::MutableArrayRef< Designator > designators()
Definition: Expr.h:5242
This represents one expression.
Definition: Expr.h:110
Describes an C or C++ initializer list.
Definition: Expr.h:4800
ArrayRef< Expr * > inits()
Definition: Expr.h:4840
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1924
A member reference to an MSPropertyDecl.
Definition: ExprCXX.h:929
MSPropertyDecl * getPropertyDecl() const
Definition: ExprCXX.h:983
SourceLocation getMemberLoc() const
Definition: ExprCXX.h:985
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3175
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'.
Definition: Expr.h:3360
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:3254
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:1793
This represents a decl that may have a name.
Definition: Decl.h:247
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition: ExprObjC.h:191
ObjCMethodDecl * getArrayWithObjectsMethod() const
Definition: ExprObjC.h:240
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:127
ObjCMethodDecl * getBoxingMethod() const
Definition: ExprObjC.h:146
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:309
ObjCMethodDecl * getDictWithObjectsMethod() const
Definition: ExprObjC.h:376
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:548
SourceLocation getLocation() const
Definition: ExprObjC.h:589
ObjCIvarDecl * getDecl()
Definition: ExprObjC.h:576
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:942
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
Definition: ExprObjC.h:1220
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:1091
const ObjCMethodDecl * getMethodDecl() const
Definition: ExprObjC.h:1346
QualType getReceiverType() const
Retrieve the receiver type to which this message is being directed.
Definition: ExprObjC.cpp:300
SourceLocation getSelectorStartLoc() const
Definition: ExprObjC.h:1409
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
Represents a pointer to an Objective C object.
Definition: Type.h:6297
Represents a class type in Objective C.
Definition: Type.h:6043
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:614
ObjCPropertyDecl * getExplicitProperty() const
Definition: ExprObjC.h:703
ObjCMethodDecl * getImplicitPropertyGetter() const
Definition: ExprObjC.h:708
bool isExplicitProperty() const
Definition: ExprObjC.h:701
SourceLocation getLocation() const
Definition: ExprObjC.h:759
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition: ExprObjC.h:504
ObjCProtocolDecl * getProtocol() const
Definition: ExprObjC.h:521
SourceLocation getProtocolIdLoc() const
Definition: ExprObjC.h:524
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2457
Helper class for OffsetOfExpr.
Definition: Expr.h:2351
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition: Expr.h:2415
@ Field
A field.
Definition: Expr.h:2358
Kind getKind() const
Determine what kind of offsetof node this is.
Definition: Expr.h:2405
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Expr.h:2438
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Definition: ExprCXX.h:2954
SourceLocation getNameLoc() const
Gets the location of the name.
Definition: ExprCXX.h:3066
llvm::iterator_range< decls_iterator > decls() const
Definition: ExprCXX.h:3052
Represents a parameter to a function.
Definition: Decl.h:1722
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6107
A (possibly-)qualified type.
Definition: Type.h:736
const Type * getTypePtrOrNull() const
Definition: Type.h:6653
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool dataTraverseStmtPre(Stmt *S)
Invoked before visiting a statement or expression via data recursion.
bool dataTraverseStmtPost(Stmt *S)
Invoked after visiting a statement or expression via data recursion.
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
bool TraverseTypeLoc(TypeLoc TL)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
bool TraverseTypeConstraint(const TypeConstraint *C)
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init)
Recursively visit a lambda capture.
bool shouldWalkTypesOfTypeLocs() const
Return whether this visitor should recurse into the types of TypeLocs.
Encodes a location in the source.
Stmt - This represents one statement.
Definition: Stmt.h:72
child_range children()
Definition: Stmt.cpp:286
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:337
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:5377
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
Definition: Type.h:5443
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
The base class of the type hierarchy.
Definition: Type.h:1566
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7424
bool shouldIndexFunctionLocalSymbols() const
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC=nullptr)
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:799
void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent, const DeclContext *DC=nullptr, bool isBase=false, bool isIBType=false)
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
Definition: IndexBody.cpp:495
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:812
bool handleReference(const NamedDecl *D, SourceLocation Loc, const NamedDecl *Parent, const DeclContext *DC, SymbolRoleSet Roles=SymbolRoleSet(), ArrayRef< SymbolRelation > Relations=std::nullopt, const Expr *RefE=nullptr, const Decl *RefD=nullptr)
bool handleDecl(const Decl *D, SymbolRoleSet Roles=SymbolRoleSet(), ArrayRef< SymbolRelation > Relations=std::nullopt)
bool isFunctionLocalSymbol(const Decl *D)
Definition: IndexSymbol.cpp:53
unsigned SymbolRoleSet
Definition: IndexSymbol.h:133
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
@ C
Languages that the frontend can parse and compile.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition: ASTLambda.h:27
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.