24 IndexingContext &IndexCtx;
25 const NamedDecl *Parent;
26 const DeclContext *ParentDC;
27 SmallVector<Stmt*, 16> StmtStack;
29 typedef RecursiveASTVisitor<BodyIndexer> base;
31 Stmt *getParentStmt()
const {
32 return StmtStack.size() < 2 ?
nullptr : StmtStack.end()[-2];
35 BodyIndexer(IndexingContext &indexCtx,
36 const NamedDecl *Parent,
const DeclContext *DC)
37 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
39 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
41 bool dataTraverseStmtPre(Stmt *S) {
42 StmtStack.push_back(S);
46 bool dataTraverseStmtPost(Stmt *S) {
47 assert(StmtStack.back() == S);
52 bool TraverseTypeLoc(TypeLoc TL) {
53 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
58 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
63 SmallVectorImpl<SymbolRelation> &Relations) {
65 assert(!StmtStack.empty() && E == StmtStack.back());
66 if (StmtStack.size() == 1)
68 auto It = StmtStack.end()-2;
70 if (
auto ICE = dyn_cast<ImplicitCastExpr>(*It)) {
71 if (ICE->getCastKind() == CK_LValueToRValue)
72 Roles |= (unsigned)SymbolRole::Read;
74 if (It == StmtStack.begin())
78 const Stmt *Parent = *It;
80 if (
auto BO = dyn_cast<BinaryOperator>(Parent)) {
81 if (BO->getOpcode() == BO_Assign) {
82 if (BO->getLHS()->IgnoreParenCasts() == E)
83 Roles |= (unsigned)SymbolRole::Write;
84 }
else if (
auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
85 if (CA->getLHS()->IgnoreParenCasts() == E) {
86 Roles |= (unsigned)SymbolRole::Read;
87 Roles |= (unsigned)SymbolRole::Write;
90 }
else if (
auto UO = dyn_cast<UnaryOperator>(Parent)) {
91 if (UO->isIncrementDecrementOp()) {
92 Roles |= (unsigned)SymbolRole::Read;
93 Roles |= (unsigned)SymbolRole::Write;
94 }
else if (UO->getOpcode() == UO_AddrOf) {
95 Roles |= (unsigned)SymbolRole::AddressOf;
98 }
else if (
auto CE = dyn_cast<CallExpr>(Parent)) {
99 if (CE->getCallee()->IgnoreParenCasts() == E) {
100 addCallRole(Roles, Relations);
101 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
102 if (
auto *CXXMD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
103 if (CXXMD->isVirtual() && !ME->hasQualifier()) {
104 Roles |= (unsigned)SymbolRole::Dynamic;
105 auto BaseTy = ME->getBase()->IgnoreImpCasts()->getType();
106 if (!BaseTy.isNull())
107 if (
auto *CXXRD = BaseTy->getPointeeCXXRecordDecl())
108 Relations.emplace_back((
unsigned)SymbolRole::RelationReceivedBy,
112 }
else if (
auto CXXOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
113 if (CXXOp->getNumArgs() > 0 && CXXOp->getArg(0)->IgnoreParenCasts() == E) {
115 if (Op == OO_Equal) {
116 Roles |= (unsigned)SymbolRole::Write;
117 }
else if ((Op >= OO_PlusEqual && Op <= OO_PipeEqual) ||
118 Op == OO_LessLessEqual || Op == OO_GreaterGreaterEqual ||
119 Op == OO_PlusPlus || Op == OO_MinusMinus) {
120 Roles |= (unsigned)SymbolRole::Read;
121 Roles |= (unsigned)SymbolRole::Write;
122 }
else if (Op == OO_Amp) {
123 Roles |= (unsigned)SymbolRole::AddressOf;
133 SmallVectorImpl<SymbolRelation> &Relations) {
137 Roles |= (unsigned)SymbolRole::Call;
138 if (
auto *FD = dyn_cast<FunctionDecl>(ParentDC))
139 Relations.emplace_back((
unsigned)SymbolRole::RelationCalledBy, FD);
140 else if (
auto *MD = dyn_cast<ObjCMethodDecl>(ParentDC))
141 Relations.emplace_back((
unsigned)SymbolRole::RelationCalledBy, MD);
144 bool VisitDeclRefExpr(DeclRefExpr *E) {
145 SmallVector<SymbolRelation, 4> Relations;
148 Parent, ParentDC, Roles, Relations, E);
151 bool VisitGotoStmt(GotoStmt *S) {
156 bool VisitCXXNewExpr(CXXNewExpr *E) {
163 bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
170 bool VisitLabelStmt(LabelStmt *S) {
171 if (IndexCtx.shouldIndexFunctionLocalSymbols())
172 return IndexCtx.handleDecl(S->
getDecl());
176 bool VisitMemberExpr(MemberExpr *E) {
180 SmallVector<SymbolRelation, 4> Relations;
183 Parent, ParentDC, Roles, Relations, E);
186 bool indexDependentReference(
const Expr *E, SourceLocation Loc,
187 std::vector<const NamedDecl *> TargetSymbols) {
189 if (TargetSymbols.size() != 1)
193 SmallVector<SymbolRelation, 4> Relations;
195 return IndexCtx.handleReference(TargetSymbols[0], Loc, Parent, ParentDC,
196 Roles, Relations, E);
199 bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
200 auto *Resolver = IndexCtx.getResolver();
203 Resolver->resolveMemberExpr(E));
206 bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
207 auto *Resolver = IndexCtx.getResolver();
210 Resolver->resolveDeclRefExpr(E));
213 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
214 for (DesignatedInitExpr::Designator &D : llvm::reverse(E->
designators())) {
215 if (D.isFieldDesignator()) {
216 if (
const FieldDecl *FD = D.getFieldDecl()) {
217 return IndexCtx.handleReference(FD, D.getFieldLoc(), Parent,
225 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
226 SmallVector<SymbolRelation, 4> Relations;
229 Parent, ParentDC, Roles, Relations, E);
232 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
233 auto isDynamic = [](
const ObjCMessageExpr *MsgE)->
bool {
236 if (
auto *RecE = dyn_cast<ObjCMessageExpr>(
237 MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
238 if (RecE->getMethodFamily() ==
OMF_alloc)
246 SmallVector<SymbolRelation, 2> Relations;
247 addCallRole(Roles, Relations);
248 Stmt *Containing = getParentStmt();
250 auto IsImplicitProperty = [](
const PseudoObjectExpr *POE) ->
bool {
251 const auto *E = POE->getSyntacticForm();
252 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E))
254 const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E);
257 if (PRE->isExplicitProperty())
259 if (
const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
263 if (Getter->isClassMethod() &&
264 Getter->getCanonicalDecl()->findPropertyDecl())
269 bool IsPropCall = isa_and_nonnull<PseudoObjectExpr>(Containing);
274 Roles |= (unsigned)SymbolRole::Implicit;
277 Roles |= (unsigned)SymbolRole::Dynamic;
279 auto addReceivers = [&](
const ObjCObjectType *Ty) {
282 if (
const auto *clsD = Ty->getInterface()) {
283 Relations.emplace_back((
unsigned)SymbolRole::RelationReceivedBy,
286 for (
const auto *protD : Ty->quals()) {
287 Relations.emplace_back((
unsigned)SymbolRole::RelationReceivedBy,
292 if (
const auto *Ptr = recT->
getAs<ObjCObjectPointerType>())
293 addReceivers(Ptr->getObjectType());
295 addReceivers(recT->
getAs<ObjCObjectType>());
299 Parent, ParentDC, Roles, Relations, E);
304 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
306 SmallVector<SymbolRelation, 2> Relations;
309 Parent, ParentDC, Roles, Relations, E);
314 if (Getter->isClassMethod()) {
315 if (
const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
316 SmallVector<SymbolRelation, 2> Relations;
318 return IndexCtx.handleReference(PD, E->
getLocation(), Parent,
319 ParentDC, Roles, Relations, E);
329 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
334 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
339 bool passObjCLiteralMethodCall(
const ObjCMethodDecl *MD,
const Expr *E) {
341 SmallVector<SymbolRelation, 2> Relations;
342 addCallRole(Roles, Relations);
343 Roles |= (unsigned)SymbolRole::Implicit;
344 return IndexCtx.handleReference(MD, E->
getBeginLoc(), Parent, ParentDC,
345 Roles, Relations, E);
348 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
350 return passObjCLiteralMethodCall(MD, E);
355 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
357 return passObjCLiteralMethodCall(MD, E);
362 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
364 return passObjCLiteralMethodCall(MD, E);
369 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
371 SmallVector<SymbolRelation, 2> Relations;
372 addCallRole(Roles, Relations);
374 Parent, ParentDC, Roles, Relations, E);
378 DataRecursionQueue *Q =
nullptr) {
381 return base::TraverseCXXOperatorCallExpr(E, Q);
384 bool VisitDeclStmt(DeclStmt *S) {
385 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
396 IndexCtx.indexTopLevelDecl(D);
402 bool TraverseLambdaCapture(
LambdaExpr *LE,
const LambdaCapture *
C,
404 if (
C->capturesThis() ||
C->capturesVLAType())
410 if (
C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
411 return IndexCtx.handleReference(
C->getCapturedVar(),
C->getLocation(),
421 bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q =
nullptr) {
422 auto visitForm = [&](InitListExpr *Form) {
423 for (Stmt *SubStmt : Form->children()) {
424 if (!TraverseStmt(SubStmt, Q))
430 auto visitSyntacticDesignatedInitExpr = [&](DesignatedInitExpr *E) ->
bool {
431 for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
432 if (D.isFieldDesignator()) {
433 if (
const FieldDecl *FD = D.getFieldDecl()) {
434 return IndexCtx.handleReference(FD, D.getFieldLoc(), Parent,
439 if (D.isArrayDesignator())
440 TraverseStmt(E->getArrayIndex(D));
441 else if (D.isArrayRangeDesignator()) {
442 TraverseStmt(E->getArrayRangeStart(D));
443 TraverseStmt(E->getArrayRangeEnd(D));
456 for (Expr *init : SyntaxForm->
inits()) {
457 if (
auto *DIE = dyn_cast<DesignatedInitExpr>(init))
458 visitSyntacticDesignatedInitExpr(DIE);
461 return visitForm(SemaForm);
466 return visitForm(SyntaxForm);
472 bool VisitOffsetOfExpr(OffsetOfExpr *S) {
483 bool VisitParmVarDecl(ParmVarDecl* D) {
485 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
488 IndexCtx.handleDecl(D);
493 bool VisitOverloadExpr(OverloadExpr *E) {
494 SmallVector<SymbolRelation, 4> Relations;
496 for (
auto *D : E->
decls())
497 IndexCtx.handleReference(D, E->
getNameLoc(), Parent, ParentDC, Roles,
502 bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *R) {
508 bool TraverseTypeConstraint(
const TypeConstraint *
C) {
509 IndexCtx.handleReference(
C->getNamedConcept(),
C->getConceptNameLoc(),
524 BodyIndexer(*
this, Parent, DC).TraverseStmt(
const_cast<Stmt*
>(S));
This file provides AST data structures related to concepts.
This file provides some common utility functions for processing Lambda related AST Constructs.
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)
bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S)
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.
SourceLocation getLocation() const
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
FunctionDecl * getOperatorDelete() const
SourceLocation getBeginLoc() const
bool isGlobalDelete() const
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the name of the member that this expression refers to.
SourceLocation getBeginLoc() const
FunctionDecl * getOperatorNew() const
SourceLocation getOperatorLoc() const
Returns the location of the operator symbol in the expression.
SourceLocation getConceptNameLoc() const
ConceptDecl * getNamedConcept() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
SourceLocation getLocation() const
const DeclGroupRef getDeclGroup() const
DeclContext * getDeclContext()
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
MutableArrayRef< Designator > designators()
SourceLocation getLabelLoc() const
LabelDecl * getLabel() const
bool isSemanticForm() const
InitListExpr * getSyntacticForm() const
InitListExpr * getSemanticForm() const
ArrayRef< Expr * > inits()
LabelDecl * getDecl() const
MSPropertyDecl * getPropertyDecl() const
SourceLocation getMemberLoc() const
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents a decl that may have a name.
ObjCMethodDecl * getArrayWithObjectsMethod() const
ObjCMethodDecl * getBoxingMethod() const
ObjCMethodDecl * getDictWithObjectsMethod() const
SourceLocation getLocation() const
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
@ Instance
The receiver is an object instance.
const ObjCMethodDecl * getMethodDecl() const
QualType getReceiverType() const
Retrieve the receiver type to which this message is being directed.
SourceLocation getSelectorStartLoc() const
ObjCPropertyDecl * getExplicitProperty() const
ObjCMethodDecl * getImplicitPropertyGetter() const
bool isExplicitProperty() const
SourceLocation getLocation() const
ObjCProtocolDecl * getProtocol() const
SourceLocation getProtocolIdLoc() const
const OffsetOfNode & getComponent(unsigned Idx) const
unsigned getNumComponents() const
FieldDecl * getField() const
For a field offsetof node, returns the field.
Kind getKind() const
Determine what kind of offsetof node this is.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getNameLoc() const
Gets the location of the name.
llvm::iterator_range< decls_iterator > decls() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
bool TraverseTypeConstraint(const TypeConstraint *C)
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
const T * getAs() const
Member-template getAs<specific type>'.
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
bool isFunctionLocalSymbol(const Decl *D)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallOperator(const CXXMethodDecl *MD)
U cast(CodeGen::Address addr)
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.