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 && BO->getLHS()->IgnoreParenCasts() == E)
81 Roles |= (
unsigned)SymbolRole::Write;
83 }
else if (
auto UO = dyn_cast<UnaryOperator>(Parent)) {
84 if (UO->isIncrementDecrementOp()) {
86 Roles |= (
unsigned)SymbolRole::Write;
87 }
else if (UO->getOpcode() == UO_AddrOf) {
88 Roles |= (
unsigned)SymbolRole::AddressOf;
91 }
else if (
auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
92 if (CA->getLHS()->IgnoreParenCasts() == E) {
94 Roles |= (
unsigned)SymbolRole::Write;
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);
154 Parent, ParentDC, Roles, Relations, E);
157 bool indexDependentReference(
159 llvm::function_ref<
bool(
const NamedDecl *ND)> Filter) {
175 std::vector<const NamedDecl *> Symbols =
178 if (Symbols.size() != 1)
185 return IndexCtx.
handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
191 return indexDependentReference(
193 [](
const NamedDecl *D) { return D->isCXXInstanceMember(); });
199 return indexDependentReference(
201 [](
const NamedDecl *D) { return !D->isCXXInstanceMember(); });
206 if (D.isFieldDesignator() && D.getField())
217 Parent, ParentDC, Roles, Relations, E);
224 if (
auto *RecE = dyn_cast<ObjCMessageExpr>(
225 MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
226 if (RecE->getMethodFamily() ==
OMF_alloc)
235 addCallRole(Roles, Relations);
236 Stmt *Containing = getParentStmt();
239 const auto *E = POE->getSyntacticForm();
240 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E))
242 const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E);
245 if (PRE->isExplicitProperty())
247 if (
const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
251 if (Getter->isClassMethod() &&
252 Getter->getCanonicalDecl()->findPropertyDecl())
257 bool IsPropCall = Containing && isa<PseudoObjectExpr>(Containing);
261 IsImplicitProperty(cast<PseudoObjectExpr>(Containing))))
262 Roles |= (
unsigned)SymbolRole::Implicit;
265 Roles |= (
unsigned)SymbolRole::Dynamic;
270 if (
const auto *clsD = Ty->getInterface()) {
271 Relations.emplace_back((
unsigned)SymbolRole::RelationReceivedBy,
274 for (
const auto *protD : Ty->quals()) {
275 Relations.emplace_back((
unsigned)SymbolRole::RelationReceivedBy,
281 addReceivers(Ptr->getObjectType());
287 Parent, ParentDC, Roles, Relations, E);
297 Parent, ParentDC, Roles, Relations, E);
302 if (Getter->isClassMethod()) {
303 if (
const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
307 ParentDC, Roles, Relations, E);
330 addCallRole(Roles, Relations);
331 Roles |= (
unsigned)SymbolRole::Implicit;
333 Roles, Relations, E);
338 return passObjCLiteralMethodCall(MD, E);
345 return passObjCLiteralMethodCall(MD, E);
352 return passObjCLiteralMethodCall(MD, E);
360 addCallRole(Roles, Relations);
362 Parent, ParentDC, Roles, Relations, E);
366 DataRecursionQueue *Q =
nullptr) {
369 return base::TraverseCXXOperatorCallExpr(E, Q);
392 if (
C->capturesThis() ||
C->capturesVLAType())
409 bool TraverseInitListExpr(
InitListExpr *S, DataRecursionQueue *Q =
nullptr) {
420 if (D.isFieldDesignator() && D.getField())
428 InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
429 InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
435 if (
auto *DIE = dyn_cast<DesignatedInitExpr>(init))
436 visitSyntacticDesignatedInitExpr(DIE);
439 return visitForm(SemaForm);
444 return visitForm(SyntaxForm);
451 for (
unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
474 for (
auto *D : E->
decls())
501 DC =
Parent->getLexicalDeclContext();
502 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.
SourceLocation getConceptNameLoc() const
ConceptDecl * getNamedConcept() const
Represents the specialization of a concept - evaluates to a prvalue of type bool.
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.
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
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.
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)
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
bool indexDeclGroupRef(DeclGroupRef DG)
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)
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ C
Languages that the frontend can parse and compile.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
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.