30 Stmt *getParentStmt()
const {
31 return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2];
41 StmtStack.push_back(S);
46 assert(StmtStack.back() == S);
64 assert(!StmtStack.empty() &&
E == StmtStack.back());
65 if (StmtStack.size() == 1)
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;
73 if (It == StmtStack.begin())
79 if (
auto BO = dyn_cast<BinaryOperator>(Parent)) {
80 if (BO->getOpcode() == BO_Assign) {
81 if (BO->getLHS()->IgnoreParenCasts() ==
E)
82 Roles |= (
unsigned)SymbolRole::Write;
83 }
else if (
auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
84 if (CA->getLHS()->IgnoreParenCasts() ==
E) {
86 Roles |= (
unsigned)SymbolRole::Write;
89 }
else if (
auto UO = dyn_cast<UnaryOperator>(Parent)) {
90 if (UO->isIncrementDecrementOp()) {
92 Roles |= (
unsigned)SymbolRole::Write;
93 }
else if (UO->getOpcode() == UO_AddrOf) {
94 Roles |= (
unsigned)SymbolRole::AddressOf;
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,
111 }
else if (
auto CXXOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
112 if (CXXOp->getNumArgs() > 0 && CXXOp->getArg(0)->IgnoreParenCasts() ==
E) {
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;
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);
144 Parent, ParentDC, Roles, Relations,
E);
148 return IndexCtx.
handleReference(S->getLabel(), S->getLabelLoc(), Parent,
165 Parent, ParentDC, Roles, Relations,
E);
168 bool indexDependentReference(
170 llvm::function_ref<
bool(
const NamedDecl *ND)> Filter) {
186 std::vector<const NamedDecl *> Symbols =
189 if (Symbols.size() != 1)
202 return indexDependentReference(
203 E,
E->getBaseType().getTypePtrOrNull(), Info,
204 [](
const NamedDecl *
D) { return D->isCXXInstanceMember(); });
210 return indexDependentReference(
212 [](
const NamedDecl *
D) { return !D->isCXXInstanceMember(); });
217 if (
D.isFieldDesignator()) {
231 Parent, ParentDC, Roles, Relations,
E);
238 if (
auto *RecE = dyn_cast<ObjCMessageExpr>(
239 MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
240 if (RecE->getMethodFamily() ==
OMF_alloc)
249 addCallRole(Roles, Relations);
250 Stmt *Containing = getParentStmt();
253 const auto *
E = POE->getSyntacticForm();
254 if (
const auto *BinOp = dyn_cast<BinaryOperator>(
E))
256 const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(
E);
259 if (PRE->isExplicitProperty())
261 if (
const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
265 if (Getter->isClassMethod() &&
266 Getter->getCanonicalDecl()->findPropertyDecl())
271 bool IsPropCall = isa_and_nonnull<PseudoObjectExpr>(Containing);
273 if ((
E->isImplicit() || IsPropCall) &&
275 IsImplicitProperty(cast<PseudoObjectExpr>(Containing))))
276 Roles |= (
unsigned)SymbolRole::Implicit;
279 Roles |= (
unsigned)SymbolRole::Dynamic;
284 if (
const auto *clsD = Ty->getInterface()) {
285 Relations.emplace_back((
unsigned)SymbolRole::RelationReceivedBy,
288 for (
const auto *protD : Ty->quals()) {
289 Relations.emplace_back((
unsigned)SymbolRole::RelationReceivedBy,
295 addReceivers(Ptr->getObjectType());
301 Parent, ParentDC, Roles, Relations,
E);
307 if (
E->isExplicitProperty()) {
311 Parent, ParentDC, Roles, Relations,
E);
312 }
else if (
const ObjCMethodDecl *Getter =
E->getImplicitPropertyGetter()) {
316 if (Getter->isClassMethod()) {
317 if (
const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
321 ParentDC, Roles, Relations,
E);
344 addCallRole(Roles, Relations);
345 Roles |= (
unsigned)SymbolRole::Implicit;
347 Roles, Relations,
E);
352 return passObjCLiteralMethodCall(MD,
E);
359 return passObjCLiteralMethodCall(MD,
E);
366 return passObjCLiteralMethodCall(MD,
E);
374 addCallRole(Roles, Relations);
376 Parent, ParentDC, Roles, Relations,
E);
380 DataRecursionQueue *Q =
nullptr) {
381 if (
E->getOperatorLoc().isInvalid())
383 return base::TraverseCXXOperatorCallExpr(
E, Q);
406 if (
C->capturesThis() ||
C->capturesVLAType())
423 bool TraverseInitListExpr(
InitListExpr *S, DataRecursionQueue *Q =
nullptr) {
434 if (
D.isFieldDesignator()) {
445 InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
446 InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
452 if (
auto *DIE = dyn_cast<DesignatedInitExpr>(init))
453 visitSyntacticDesignatedInitExpr(DIE);
456 return visitForm(SemaForm);
461 return visitForm(SyntaxForm);
468 for (
unsigned I = 0,
E = S->getNumComponents(); I !=
E; ++I) {
491 for (
auto *
D :
E->decls())
518 DC =
Parent->getLexicalDeclContext();
519 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.
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.
Represents a C++ member access expression where the actual member referenced could not be resolved be...
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
CXXRecordDecl * getDefinition() const
bool hasDefinition() const
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.
Represents the specialization of a concept - evaluates to a prvalue of type bool.
SourceLocation getConceptNameLoc() const
ConceptDecl * getNamedConcept() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
DeclContext * getDeclContext()
A qualified reference to a name whose declaration cannot yet be resolved.
Represents a single C99 designator.
Represents a C99 designated initializer expression.
This represents one expression.
Represents a member of a struct/union/class.
GotoStmt - This represents a direct goto.
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
LabelStmt - Represents a label, which has a substatement.
Describes the capture of a variable or of this, or of a C++1y init-capture.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
A member reference to an MSPropertyDecl.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
This represents a decl that may have a name.
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,...
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
@ Instance
The receiver is an object instance.
ObjCMethodDecl - Represents an instance or class method declaration.
Represents a pointer to an Objective C object.
Represents a class type in Objective C.
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCProtocolExpr used for protocol expression in Objective-C.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
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
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Represents a parameter to a function.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
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.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a C++ template name within the type system.
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...
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
const T * getAs() const
Member-template getAs<specific type>'.
bool shouldIndexFunctionLocalSymbols() const
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC=nullptr)
bool indexTopLevelDecl(const Decl *D)
void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent, const DeclContext *DC=nullptr, bool isBase=false, bool isIBType=false)
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)
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
bool indexDeclGroupRef(DeclGroupRef DG)
bool handleDecl(const Decl *D, SymbolRoleSet Roles=SymbolRoleSet(), ArrayRef< SymbolRelation > Relations=std::nullopt)
bool isFunctionLocalSymbol(const Decl *D)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
const FunctionProtoType * T
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.