clang 20.0.0git
ExprMutationAnalyzer.h
Go to the documentation of this file.
1//===---------- ExprMutationAnalyzer.h ------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
9#define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
10
12#include "llvm/ADT/DenseMap.h"
13#include <memory>
14
15namespace clang {
16
17class FunctionParmMutationAnalyzer;
18
19/// Analyzes whether any mutative operations are applied to an expression within
20/// a given statement.
23
24public:
25 struct Memoized {
26 using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
28 llvm::SmallDenseMap<const FunctionDecl *,
29 std::unique_ptr<FunctionParmMutationAnalyzer>>;
30
34
35 void clear() {
36 Results.clear();
37 PointeeResults.clear();
38 FuncParmAnalyzer.clear();
39 }
40 };
41 struct Analyzer {
42 Analyzer(const Stmt &Stm, ASTContext &Context, Memoized &Memorized)
43 : Stm(Stm), Context(Context), Memorized(Memorized) {}
44
45 const Stmt *findMutation(const Expr *Exp);
46 const Stmt *findMutation(const Decl *Dec);
47
48 const Stmt *findPointeeMutation(const Expr *Exp);
49 const Stmt *findPointeeMutation(const Decl *Dec);
50
51 private:
52 using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
53
54 const Stmt *findMutationMemoized(const Expr *Exp,
56 Memoized::ResultMap &MemoizedResults);
57 const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
58
59 const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
60 const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
61 const Stmt *
62 findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
63 const Stmt *
64 findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
65
66 const Stmt *findDirectMutation(const Expr *Exp);
67 const Stmt *findMemberMutation(const Expr *Exp);
68 const Stmt *findArrayElementMutation(const Expr *Exp);
69 const Stmt *findCastMutation(const Expr *Exp);
70 const Stmt *findRangeLoopMutation(const Expr *Exp);
71 const Stmt *findReferenceMutation(const Expr *Exp);
72 const Stmt *findFunctionArgMutation(const Expr *Exp);
73
74 const Stmt &Stm;
75 ASTContext &Context;
76 Memoized &Memorized;
77 };
78
79 ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
80 : Memorized(), A(Stm, Context, Memorized) {}
81
82 /// check whether stmt is unevaluated. mutation analyzer will ignore the
83 /// content in unevaluated stmt.
84 static bool isUnevaluated(const Stmt *Stm, ASTContext &Context);
85
86 bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
87 bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
88 const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); }
89 const Stmt *findMutation(const Decl *Dec) { return A.findMutation(Dec); }
90
91 bool isPointeeMutated(const Expr *Exp) {
92 return findPointeeMutation(Exp) != nullptr;
93 }
94 bool isPointeeMutated(const Decl *Dec) {
95 return findPointeeMutation(Dec) != nullptr;
96 }
97 const Stmt *findPointeeMutation(const Expr *Exp) {
98 return A.findPointeeMutation(Exp);
99 }
100 const Stmt *findPointeeMutation(const Decl *Dec) {
101 return A.findPointeeMutation(Dec);
102 }
103
104private:
105 Memoized Memorized;
106 Analyzer A;
107};
108
109// A convenient wrapper around ExprMutationAnalyzer for analyzing function
110// params.
112public:
116 auto it = Memorized.FuncParmAnalyzer.find(&Func);
117 if (it == Memorized.FuncParmAnalyzer.end()) {
118 // Creating a new instance of FunctionParmMutationAnalyzer below may add
119 // additional elements to FuncParmAnalyzer. If we did try_emplace before
120 // creating a new instance, the returned iterator of try_emplace could be
121 // invalidated.
122 it =
123 Memorized.FuncParmAnalyzer
124 .try_emplace(&Func, std::unique_ptr<FunctionParmMutationAnalyzer>(
126 Func, Context, Memorized)))
127 .first;
128 }
129 return it->getSecond().get();
130 }
131
132 bool isMutated(const ParmVarDecl *Parm) {
133 return findMutation(Parm) != nullptr;
134 }
135 const Stmt *findMutation(const ParmVarDecl *Parm);
136
137private:
139 llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results;
140
143};
144
145} // namespace clang
146
147#endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Analyzes whether any mutative operations are applied to an expression within a given statement.
const Stmt * findMutation(const Expr *Exp)
static bool isUnevaluated(const Stmt *Stm, ASTContext &Context)
check whether stmt is unevaluated.
bool isMutated(const Decl *Dec)
bool isPointeeMutated(const Expr *Exp)
const Stmt * findMutation(const Decl *Dec)
const Stmt * findPointeeMutation(const Expr *Exp)
bool isMutated(const Expr *Exp)
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
bool isPointeeMutated(const Decl *Dec)
const Stmt * findPointeeMutation(const Decl *Dec)
This represents one expression.
Definition: Expr.h:110
Represents a function declaration or definition.
Definition: Decl.h:1935
static FunctionParmMutationAnalyzer * getFunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context, ExprMutationAnalyzer::Memoized &Memorized)
bool isMutated(const ParmVarDecl *Parm)
const Stmt * findMutation(const ParmVarDecl *Parm)
Represents a parameter to a function.
Definition: Decl.h:1725
Stmt - This represents one statement.
Definition: Stmt.h:84
The JSON file list parser is used to communicate input to InstallAPI.
Analyzer(const Stmt &Stm, ASTContext &Context, Memoized &Memorized)
const Stmt * findPointeeMutation(const Expr *Exp)
const Stmt * findMutation(const Expr *Exp)
llvm::SmallDenseMap< const FunctionDecl *, std::unique_ptr< FunctionParmMutationAnalyzer > > FunctionParaAnalyzerMap
llvm::DenseMap< const Expr *, const Stmt * > ResultMap