15#include "llvm/ADT/STLExtras.h"
18using namespace ast_matchers;
27 const auto IgnoreDerivedToBase = [](
const Expr *
E,
auto Matcher) {
30 if (
const auto *Cast = dyn_cast<ImplicitCastExpr>(
E)) {
31 if ((Cast->getCastKind() == CK_DerivedToBase ||
32 Cast->getCastKind() == CK_UncheckedDerivedToBase) &&
33 Matcher(Cast->getSubExpr()))
39 const auto EvalCommaExpr = [](
const Expr *
E,
auto Matcher) {
41 while (
const auto *BOComma =
42 dyn_cast_or_null<BinaryOperator>(
Result->IgnoreParens())) {
43 if (!BOComma->isCommaOp())
45 Result = BOComma->getRHS();
58 const auto ConditionalOperatorM = [
Target](
const Expr *
E) {
59 if (
const auto *CO = dyn_cast<AbstractConditionalOperator>(
E)) {
60 const auto *TE = CO->getTrueExpr()->IgnoreParens();
63 const auto *FE = CO->getFalseExpr()->IgnoreParens();
71 return IgnoreDerivedToBase(SourceExprP,
73 return E ==
Target || ConditionalOperatorM(
E);
75 EvalCommaExpr(SourceExprP, [&](
const Expr *
E) {
76 return IgnoreDerivedToBase(
86 return llvm::is_contained(
Node.capture_inits(),
E);
90 ast_matchers::internal::Matcher<DeclStmt>, InnerMatcher) {
91 const DeclStmt *
const Range =
Node.getRangeStmt();
92 return InnerMatcher.matches(*
Range, Finder, Builder);
96 auto *Exp = dyn_cast<Expr>(&
Node);
99 auto *
Target = dyn_cast<Expr>(Inner);
107class ExprPointeeResolve {
110 bool resolveExpr(
const Expr *
E) {
116 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
117 if (BO->isAdditiveOp())
118 return (resolveExpr(BO->getLHS()) || resolveExpr(BO->getRHS()));
120 return resolveExpr(BO->getRHS());
124 if (
const auto *PE = dyn_cast<ParenExpr>(
E))
125 return resolveExpr(PE->getSubExpr());
127 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
131 if (kind == CK_LValueToRValue || kind == CK_DerivedToBase ||
132 kind == CK_UncheckedDerivedToBase)
133 return resolveExpr(ICE->getSubExpr());
137 if (
const auto *ACE = dyn_cast<AbstractConditionalOperator>(
E))
138 return resolve(ACE->getTrueExpr()) || resolve(ACE->getFalseExpr());
144 ExprPointeeResolve(
const Expr *T) :
T(
T) {}
145 bool resolve(
const Expr *S) {
return resolveExpr(S); }
149 auto *Exp = dyn_cast<Expr>(&
Node);
152 auto *
Target = dyn_cast<Expr>(
T);
155 return ExprPointeeResolve{
Target}.resolve(Exp);
160AST_MATCHER_P(InitListExpr, hasAnyInit, ast_matchers::internal::Matcher<Expr>,
162 for (
const Expr *Arg :
Node.inits()) {
165 ast_matchers::internal::BoundNodesTreeBuilder
Result(*Builder);
166 if (InnerMatcher.matches(*Arg, Finder, &
Result)) {
167 *Builder = std::move(
Result);
174const ast_matchers::internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr>
177AST_MATCHER(CXXTypeidExpr, isPotentiallyEvaluated) {
178 return Node.isPotentiallyEvaluated();
182 const Decl *CalleeDecl =
Node.getCalleeDecl();
183 const auto *VD = dyn_cast_or_null<ValueDecl>(CalleeDecl);
186 const QualType
T = VD->getType().getCanonicalType();
187 const auto *MPT = dyn_cast<MemberPointerType>(
T);
188 const auto *FPT = MPT ? cast<FunctionProtoType>(MPT->getPointeeType())
189 : dyn_cast<FunctionProtoType>(
T);
192 return FPT->isConst();
196 ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
197 if (
Node.isTypePredicate())
199 return InnerMatcher.matches(*
Node.getControllingExpr(), Finder, Builder);
203ast_matchers::internal::Matcher<T>
204findFirst(
const ast_matchers::internal::Matcher<T> &Matcher) {
208const auto nonConstReferenceType = [] {
209 return hasUnqualifiedDesugaredType(
213const auto nonConstPointerType = [] {
214 return hasUnqualifiedDesugaredType(
218const auto isMoveOnly = [] {
228template <
class T>
struct NodeID;
229template <>
struct NodeID<Expr> {
static constexpr StringRef value =
"expr"; };
230template <>
struct NodeID<
Decl> {
static constexpr StringRef value =
"decl"; };
231constexpr StringRef NodeID<Expr>::value;
232constexpr StringRef NodeID<Decl>::value;
235 class F =
const Stmt *(ExprMutationAnalyzer::Analyzer::*)(
const T *)>
236const Stmt *tryEachMatch(ArrayRef<ast_matchers::BoundNodes> Matches,
237 ExprMutationAnalyzer::Analyzer *Analyzer, F Finder) {
238 const StringRef
ID = NodeID<T>::value;
239 for (
const auto &
Nodes : Matches) {
240 if (
const Stmt *S = (Analyzer->*Finder)(
Nodes.getNodeAs<
T>(
ID)))
249 return findMutationMemoized(
251 {&ExprMutationAnalyzer::Analyzer::findDirectMutation,
252 &ExprMutationAnalyzer::Analyzer::findMemberMutation,
253 &ExprMutationAnalyzer::Analyzer::findArrayElementMutation,
254 &ExprMutationAnalyzer::Analyzer::findCastMutation,
255 &ExprMutationAnalyzer::Analyzer::findRangeLoopMutation,
256 &ExprMutationAnalyzer::Analyzer::findReferenceMutation,
257 &ExprMutationAnalyzer::Analyzer::findFunctionArgMutation},
267 return findMutationMemoized(
270 &ExprMutationAnalyzer::Analyzer::findPointeeValueMutation,
271 &ExprMutationAnalyzer::Analyzer::findPointeeMemberMutation,
272 &ExprMutationAnalyzer::Analyzer::findPointeeToNonConst,
279 return tryEachDeclRef(Dec,
283const Stmt *ExprMutationAnalyzer::Analyzer::findMutationMemoized(
287 auto [
Memoized, Inserted] = MemoizedResults.try_emplace(Exp);
294 for (
const auto &Finder : Finders) {
295 if (
const Stmt *S = (this->*Finder)(Exp))
296 return MemoizedResults[Exp] = S;
303ExprMutationAnalyzer::Analyzer::tryEachDeclRef(
const Decl *Dec,
304 MutationFinder Finder) {
305 const auto Refs =
match(
309 anyOf(equalsNode(Dec),
313 .bind(NodeID<Expr>::value)),
315 for (
const auto &RefNodes : Refs) {
316 const auto *
E = RefNodes.getNodeAs<Expr>(NodeID<Expr>::value);
317 if ((this->*Finder)(
E))
338 cxxTypeidExpr(
unless(isPotentiallyEvaluated())),
350 return tryEachMatch<Expr>(Matches,
this,
355ExprMutationAnalyzer::Analyzer::findDeclMutation(ArrayRef<BoundNodes> Matches) {
356 return tryEachMatch<Decl>(Matches,
this,
360const Stmt *ExprMutationAnalyzer::Analyzer::findExprPointeeMutation(
361 ArrayRef<ast_matchers::BoundNodes> Matches) {
362 return tryEachMatch<Expr>(
366const Stmt *ExprMutationAnalyzer::Analyzer::findDeclPointeeMutation(
367 ArrayRef<ast_matchers::BoundNodes> Matches) {
368 return tryEachMatch<Decl>(
373ExprMutationAnalyzer::Analyzer::findDirectMutation(
const Expr *Exp) {
375 const auto AsAssignmentLhs =
376 binaryOperator(isAssignmentOperator(), hasLHS(canResolveToExpr(Exp)));
379 const auto AsIncDecOperand =
381 hasUnaryOperand(canResolveToExpr(Exp)));
390 hasArgument(0, canResolveToExpr(Exp))),
396 hasEitherOperand(ignoringImpCasts(canResolveToExpr(Exp)))),
400 cxxFoldExpr(hasFoldInit(ignoringImpCasts(canResolveToExpr(Exp)))),
407 hasObjectExpression(canResolveToExpr(Exp))))))),
413 hasObjectExpression(canResolveToExpr(Exp))))))));
419 const auto AsAmpersandOperand =
423 hasUnaryOperand(canResolveToExpr(Exp)));
424 const auto AsPointerFromArrayDecay =
castExpr(
425 hasCastKind(CK_ArrayToPointerDecay),
433 cxxMethodDecl(ofClass(isMoveOnly()), returns(nonConstPointerType()))),
434 argumentCountIs(1), hasArgument(0, canResolveToExpr(Exp)));
441 const auto NonConstRefParam = forEachArgumentWithParamType(
442 anyOf(canResolveToExpr(Exp),
444 hasObjectExpression(ignoringImpCasts(canResolveToExpr(Exp))))),
445 nonConstReferenceType());
448 const auto AsNonConstRefArg =
454 callExpr(isTypeDependent(), hasAnyArgument(canResolveToExpr(Exp))),
470 const auto AsLambdaRefCaptureInit =
lambdaExpr(hasCaptureInit(Exp));
477 const auto AsNonConstRefReturn =
478 returnStmt(hasReturnValue(canResolveToExpr(Exp)));
482 allOf(canResolveToExpr(Exp), hasType(nonConstReferenceType())))));
484 const auto Matches =
match(
487 findFirst(
stmt(
anyOf(AsAssignmentLhs, AsIncDecOperand, AsNonConstThis,
488 AsAmpersandOperand, AsPointerFromArrayDecay,
489 AsOperatorArrowThis, AsNonConstRefArg,
490 AsLambdaRefCaptureInit, AsNonConstRefReturn,
491 AsNonConstRefRangeInit))
494 return selectFirst<Stmt>(
"stmt", Matches);
498ExprMutationAnalyzer::Analyzer::findMemberMutation(
const Expr *Exp) {
500 const auto MemberExprs =
match(
503 hasObjectExpression(canResolveToExpr(Exp))),
505 hasLHS(equalsNode(Exp)))))
506 .bind(NodeID<Expr>::value)),
508 return findExprMutation(MemberExprs);
512ExprMutationAnalyzer::Analyzer::findArrayElementMutation(
const Expr *Exp) {
514 const auto SubscriptExprs =
match(
516 anyOf(hasBase(canResolveToExpr(Exp)),
518 hasCastKind(CK_ArrayToPointerDecay),
519 hasSourceExpression(canResolveToExpr(Exp)))))))
520 .bind(NodeID<Expr>::value)),
522 return findExprMutation(SubscriptExprs);
525const Stmt *ExprMutationAnalyzer::Analyzer::findCastMutation(
const Expr *Exp) {
528 const auto ExplicitCast =
531 nonConstReferenceType()))))
535 if (
const auto *CastStmt = selectFirst<Stmt>(
"stmt", ExplicitCast))
539 const auto Casts =
match(
542 nonConstReferenceType())),
544 nonConstReferenceType())))))
545 .bind(NodeID<Expr>::value)),
548 if (
const Stmt *S = findExprMutation(Casts))
553 hasAnyName(
"::std::move",
"::std::forward"))),
554 hasArgument(0, canResolveToExpr(Exp)))
557 return findExprMutation(Calls);
561ExprMutationAnalyzer::Analyzer::findRangeLoopMutation(
const Expr *Exp) {
568 const auto DeclStmtToNonRefToArray =
declStmt(hasSingleDecl(
varDecl(hasType(
570 const auto RefToArrayRefToElements =
match(
574 hasType(nonConstPointerType())))
575 .bind(NodeID<Decl>::value)),
576 hasRangeStmt(DeclStmtToNonRefToArray),
577 hasRangeInit(canResolveToExpr(Exp))))
581 if (
const auto *BadRangeInitFromArray =
582 selectFirst<Stmt>(
"stmt", RefToArrayRefToElements))
583 return BadRangeInitFromArray;
592 const auto HasAnyNonConstIterator =
598 const auto DeclStmtToNonConstIteratorContainer =
declStmt(
602 const auto RefToContainerBadIterators =
match(
604 hasRangeStmt(DeclStmtToNonConstIteratorContainer),
605 hasRangeInit(canResolveToExpr(Exp)))))
609 if (
const auto *BadIteratorsContainer =
610 selectFirst<Stmt>(
"stmt", RefToContainerBadIterators))
611 return BadIteratorsContainer;
615 const auto LoopVars =
617 hasLoopVariable(
varDecl(hasType(nonConstReferenceType()))
618 .bind(NodeID<Decl>::value)),
619 hasRangeInit(canResolveToExpr(Exp)))),
621 return findDeclMutation(LoopVars);
625ExprMutationAnalyzer::Analyzer::findReferenceMutation(
const Expr *Exp) {
629 const auto Ref =
match(
633 returns(nonConstReferenceType()))),
634 argumentCountIs(1), hasArgument(0, canResolveToExpr(Exp)))
635 .bind(NodeID<Expr>::value)),
637 if (
const Stmt *S = findExprMutation(Ref))
641 const auto Refs =
match(
643 varDecl(hasType(nonConstReferenceType()),
644 hasInitializer(
anyOf(
645 canResolveToExpr(Exp),
646 memberExpr(hasObjectExpression(canResolveToExpr(Exp))))),
651 hasRangeStmt(equalsBoundNode(
"stmt"))))))))
652 .bind(NodeID<Decl>::value))),
654 return findDeclMutation(Refs);
658ExprMutationAnalyzer::Analyzer::findFunctionArgMutation(
const Expr *Exp) {
659 const auto NonConstRefParam = forEachArgumentWithParam(
660 canResolveToExpr(Exp),
661 parmVarDecl(hasType(nonConstReferenceType())).bind(
"parm"));
664 const auto Matches =
match(
670 "::std::move",
"::std::forward"))))),
673 .bind(NodeID<Expr>::value))),
675 for (
const auto &
Nodes : Matches) {
676 const auto *Exp =
Nodes.getNodeAs<Expr>(NodeID<Expr>::value);
677 const auto *
Func =
Nodes.getNodeAs<FunctionDecl>(
"func");
678 if (!
Func->getBody() || !
Func->getPrimaryTemplate())
681 const auto *Parm =
Nodes.getNodeAs<ParmVarDecl>(
"parm");
682 const ArrayRef<ParmVarDecl *> AllParams =
683 Func->getPrimaryTemplate()->getTemplatedDecl()->parameters();
685 AllParams[std::min<size_t>(Parm->getFunctionScopeIndex(),
686 AllParams.size() - 1)]
688 if (
const auto *
T = ParmType->
getAs<PackExpansionType>())
689 ParmType =
T->getPattern();
693 if (
const auto *RefType = ParmType->getAs<RValueReferenceType>()) {
694 if (!RefType->getPointeeType().getQualifiers() &&
695 RefType->getPointeeType()->getAs<TemplateTypeParmType>()) {
698 *
Func, Context, Memorized);
699 if (Analyzer->findMutation(Parm))
711ExprMutationAnalyzer::Analyzer::findPointeeValueMutation(
const Expr *Exp) {
712 const auto Matches =
match(
717 hasUnaryOperand(canResolveToExprPointee(Exp))),
720 .bind(NodeID<Expr>::value))),
722 return findExprMutation(Matches);
726ExprMutationAnalyzer::Analyzer::findPointeeMemberMutation(
const Expr *Exp) {
727 const Stmt *MemberCallExpr = selectFirst<Stmt>(
734 return MemberCallExpr;
737 memberExpr(hasObjectExpression(canResolveToExprPointee(Exp)))
738 .bind(NodeID<Expr>::value))),
740 return findExprMutation(Matches);
744ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(
const Expr *Exp) {
745 const auto NonConstPointerOrDependentType =
746 type(
anyOf(nonConstPointerType(), isDependentType()));
749 const auto InitToNonConst =
750 varDecl(hasType(NonConstPointerOrDependentType),
751 hasInitializer(
expr(canResolveToExprPointee(Exp)).bind(
"stmt")));
752 const auto AssignToNonConst =
754 hasLHS(
expr(hasType(NonConstPointerOrDependentType))),
755 hasRHS(canResolveToExprPointee(Exp)));
757 const auto ArgOfInstantiationDependent =
allOf(
758 hasAnyArgument(canResolveToExprPointee(Exp)), isInstantiationDependent());
759 const auto ArgOfNonConstParameter = forEachArgumentWithParamType(
760 canResolveToExprPointee(Exp), NonConstPointerOrDependentType);
761 const auto CallLikeMatcher =
762 anyOf(ArgOfNonConstParameter, ArgOfInstantiationDependent);
763 const auto PassAsNonConstArg =
767 initListExpr(hasAnyInit(canResolveToExprPointee(Exp)))));
769 const auto CastToNonConst =
771 hasDestinationType(NonConstPointerOrDependentType));
775 const auto CaptureNoConst =
lambdaExpr(hasCaptureInit(Exp));
779 stmt(
anyOf(AssignToNonConst, PassAsNonConstArg,
780 CastToNonConst, CaptureNoConst))
784 return selectFirst<Stmt>(
"stmt", Matches);
787FunctionParmMutationAnalyzer::FunctionParmMutationAnalyzer(
788 const FunctionDecl &
Func, ASTContext &Context,
789 ExprMutationAnalyzer::Memoized &Memorized)
790 : BodyAnalyzer(*
Func.getBody(), Context, Memorized) {
791 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(&
Func)) {
794 for (
const CXXCtorInitializer *
Init : Ctor->inits()) {
795 ExprMutationAnalyzer::Analyzer InitAnalyzer(*
Init->getInit(), Context,
797 for (
const ParmVarDecl *Parm : Ctor->parameters()) {
798 if (Results.contains(Parm))
800 if (
const Stmt *S = InitAnalyzer.findMutation(Parm))
809 const auto Memoized = Results.find(Parm);
810 if (Memoized != Results.end())
811 return Memoized->second;
816 Results[Parm] =
nullptr;
818 return Results[Parm] = S;
819 return Results[Parm];
BoundNodesTreeBuilder Nodes
#define AST_MATCHER(Type, DefineMatcher)
AST_MATCHER(Type, DefineMatcher) { ... } defines a zero parameter function named DefineMatcher() that...
#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)
AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } defines a single-parameter function name...
llvm::MachO::Target Target
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Decl - This represents one declaration (or definition), e.g.
static bool isUnevaluated(const Stmt *Stm, ASTContext &Context)
check whether stmt is unevaluated.
friend class FunctionParmMutationAnalyzer
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
static FunctionParmMutationAnalyzer * getFunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context, ExprMutationAnalyzer::Memoized &Memorized)
const Stmt * findMutation(const ParmVarDecl *Parm)
Represents a parameter to a function.
Stmt - This represents one statement.
const T * getAs() const
Member-template getAs<specific type>'.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, DeclRefExpr > declRefExpr
Matches expressions that refer to declarations.
const internal::VariadicOperatorMatcherFunc< 1, 1 > unless
Matches if the provided matcher does not match.
const internal::VariadicDynCastAllOfMatcher< Stmt, ImplicitCastExpr > implicitCastExpr
Matches the implicit cast nodes of Clang's AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXDependentScopeMemberExpr > cxxDependentScopeMemberExpr
Matches member expressions where the actual member referenced could not be resolved because the base ...
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicDynCastAllOfMatcher< Decl, BindingDecl > bindingDecl
Matches binding declarations Example matches foo and bar (matcher = bindingDecl()
const internal::VariadicDynCastAllOfMatcher< Decl, ParmVarDecl > parmVarDecl
Matches parameter variable declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, GenericSelectionExpr > genericSelectionExpr
Matches C11 _Generic expression.
const internal::VariadicDynCastAllOfMatcher< Stmt, ReturnStmt > returnStmt
Matches return statements.
internal::Matcher< NamedDecl > hasName(StringRef Name)
Matches NamedDecl nodes that have the specified name.
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, LambdaExpr > lambdaExpr
Matches lambda expressions.
const AstTypeMatcher< VariableArrayType > variableArrayType
Matches C arrays with a specified size that is not an integer-constant-expression.
const internal::VariadicDynCastAllOfMatcher< Stmt, UnaryExprOrTypeTraitExpr > unaryExprOrTypeTraitExpr
Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
const internal::ArgumentAdaptingMatcherFunc< internal::ForEachDescendantMatcher > forEachDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
const internal::VariadicDynCastAllOfMatcher< Decl, NamedDecl > namedDecl
Matches a declaration of anything that could have a name.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< TypeLoc > typeLoc
Matches TypeLocs in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, ParenListExpr > parenListExpr
Matches paren list expressions.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
const internal::VariadicDynCastAllOfMatcher< Stmt, UnaryOperator > unaryOperator
Matches unary operator expressions.
const internal::VariadicFunction< internal::Matcher< NamedDecl >, StringRef, internal::hasAnyNameFunc > hasAnyName
Matches NamedDecl nodes that have any of the specified names.
const internal::MapAnyOfMatcher< BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator > binaryOperation
Matches nodes which can be used with binary operators.
const internal::VariadicDynCastAllOfMatcher< Stmt, ArraySubscriptExpr > arraySubscriptExpr
Matches array subscript expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXForRangeStmt > cxxForRangeStmt
Matches range-based for statements.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXMemberCallExpr > cxxMemberCallExpr
Matches member call expressions.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXConstructorDecl > cxxConstructorDecl
Matches C++ constructor declarations.
internal::BindableMatcher< Stmt > sizeOfExpr(const internal::Matcher< UnaryExprOrTypeTraitExpr > &InnerMatcher)
Same as unaryExprOrTypeTraitExpr, but only matching sizeof.
const internal::VariadicDynCastAllOfMatcher< Stmt, InitListExpr > initListExpr
Matches init list expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXNoexceptExpr > cxxNoexceptExpr
Matches noexcept expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, BinaryOperator > binaryOperator
Matches binary operator expressions.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, ExplicitCastExpr > explicitCastExpr
Matches explicit cast expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXConstructExpr > cxxConstructExpr
Matches constructor call expressions (including implicit ones).
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXOperatorCallExpr > cxxOperatorCallExpr
Matches overloaded operator calls.
internal::PolymorphicMatcher< internal::HasOverloadedOperatorNameMatcher, AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl), std::vector< std::string > > hasOverloadedOperatorName(StringRef Name)
Matches overloaded operator names.
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> allOf
Matches if all given matchers match.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, UnresolvedMemberExpr > unresolvedMemberExpr
Matches unresolved member expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, MemberExpr > memberExpr
Matches member expressions.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
internal::Matcher< T > traverse(TraversalKind TK, const internal::Matcher< T > &InnerMatcher)
Causes all nested matchers to be matched with the specified traversal kind.
const AstTypeMatcher< ReferenceType > referenceType
Matches both lvalue and rvalue reference types.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXUnresolvedConstructExpr > cxxUnresolvedConstructExpr
Matches unresolved constructor call expressions.
internal::Matcher< T > findAll(const internal::Matcher< T > &Matcher)
Matches if the node or any descendant matches.
internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher< Decl > > hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)
Matches a node if the declaration associated with that node matches the given matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, DeclStmt > declStmt
Matches declaration statements.
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXFoldExpr > cxxFoldExpr
Matches C++17 fold expressions.
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> anyOf
Matches if any of the given matchers matches.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXMethodDecl > cxxMethodDecl
Matches method declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasAncestorMatcher, internal::TypeList< Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr >, internal::TypeList< Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr > > hasAncestor
Matches AST nodes that have an ancestor that matches the provided matcher.
const internal::ArgumentAdaptingMatcherFunc< internal::HasParentMatcher, internal::TypeList< Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr >, internal::TypeList< Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr > > hasParent
Matches AST nodes that have a parent that matches the provided matcher.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
The JSON file list parser is used to communicate input to InstallAPI.
@ TK_AsIs
Will traverse all child nodes.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
static bool canExprResolveTo(const Expr *Source, const Expr *Target)
const Stmt * findPointeeMutation(const Expr *Exp)
const Stmt * findMutation(const Expr *Exp)
llvm::DenseMap< const Expr *, const Stmt * > ResultMap