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)
196 return IndexCtx.
handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
202 return indexDependentReference(
204 [](
const NamedDecl *D) { return D->isCXXInstanceMember(); });
210 return indexDependentReference(
212 [](
const NamedDecl *D) { return !D->isCXXInstanceMember(); });
217 if (D.isFieldDesignator()) {
218 if (
const FieldDecl *FD = D.getFieldDecl()) {
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 = Containing && isa<PseudoObjectExpr>(Containing);
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);
311 Parent, ParentDC, Roles, Relations, E);
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) {
383 return base::TraverseCXXOperatorCallExpr(E, Q);
406 if (
C->capturesThis() ||
C->capturesVLAType())
423 bool TraverseInitListExpr(
InitListExpr *S, DataRecursionQueue *Q =
nullptr) {
434 if (D.isFieldDesignator()) {
435 if (
const FieldDecl *FD = D.getFieldDecl()) {
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.
SourceLocation getLocation() const
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Represents a C++ member access expression where the actual member referenced could not be resolved be...
const DeclarationNameInfo & getMemberNameInfo() const
Retrieve the name of the member that this expression refers to.
QualType getBaseType() const
A call to an overloaded operator written using operator syntax.
SourceLocation getOperatorLoc() const
Returns the location of the operator symbol in the expression.
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.
SourceLocation getLocation() const
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.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
Represents a single C99 designator.
Represents a C99 designated initializer expression.
llvm::MutableArrayRef< Designator > designators()
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.
MSPropertyDecl * getPropertyDecl() const
SourceLocation getMemberLoc() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
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.
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,...
ObjCMethodDecl * getArrayWithObjectsMethod() const
ObjCBoxedExpr - used for generalized expression boxing.
ObjCMethodDecl * getBoxingMethod() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCMethodDecl * getDictWithObjectsMethod() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceLocation getLocation() const
An expression that sends a message to the given Objective-C object or class.
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
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.
ObjCPropertyDecl * getExplicitProperty() const
ObjCMethodDecl * getImplicitPropertyGetter() const
bool isExplicitProperty() const
SourceLocation getLocation() const
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCProtocolDecl * getProtocol() const
SourceLocation getProtocolIdLoc() const
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.
SourceLocation getNameLoc() const
Gets the location of the name.
llvm::iterator_range< decls_iterator > decls() const
Represents a parameter to a function.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
const Type * getTypePtrOrNull() const
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)
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
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.