aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h')
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h136
1 files changed, 94 insertions, 42 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
index 9397c5df78ab..117173ba9a09 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -8,11 +8,9 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
-#include <type_traits>
-
-#include "clang/AST/AST.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "llvm/ADT/DenseMap.h"
+#include <memory>
namespace clang {
@@ -21,14 +19,74 @@ class FunctionParmMutationAnalyzer;
/// Analyzes whether any mutative operations are applied to an expression within
/// a given statement.
class ExprMutationAnalyzer {
+ friend class FunctionParmMutationAnalyzer;
+
public:
+ struct Memoized {
+ using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
+ using FunctionParaAnalyzerMap =
+ llvm::SmallDenseMap<const FunctionDecl *,
+ std::unique_ptr<FunctionParmMutationAnalyzer>>;
+
+ ResultMap Results;
+ ResultMap PointeeResults;
+ FunctionParaAnalyzerMap FuncParmAnalyzer;
+
+ void clear() {
+ Results.clear();
+ PointeeResults.clear();
+ FuncParmAnalyzer.clear();
+ }
+ };
+ struct Analyzer {
+ Analyzer(const Stmt &Stm, ASTContext &Context, Memoized &Memorized)
+ : Stm(Stm), Context(Context), Memorized(Memorized) {}
+
+ const Stmt *findMutation(const Expr *Exp);
+ const Stmt *findMutation(const Decl *Dec);
+
+ const Stmt *findPointeeMutation(const Expr *Exp);
+ const Stmt *findPointeeMutation(const Decl *Dec);
+ static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
+ ASTContext &Context);
+
+ private:
+ using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
+
+ const Stmt *findMutationMemoized(const Expr *Exp,
+ llvm::ArrayRef<MutationFinder> Finders,
+ Memoized::ResultMap &MemoizedResults);
+ const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
+
+ bool isUnevaluated(const Expr *Exp);
+
+ const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+ const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+ const Stmt *
+ findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+ const Stmt *
+ findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+
+ const Stmt *findDirectMutation(const Expr *Exp);
+ const Stmt *findMemberMutation(const Expr *Exp);
+ const Stmt *findArrayElementMutation(const Expr *Exp);
+ const Stmt *findCastMutation(const Expr *Exp);
+ const Stmt *findRangeLoopMutation(const Expr *Exp);
+ const Stmt *findReferenceMutation(const Expr *Exp);
+ const Stmt *findFunctionArgMutation(const Expr *Exp);
+
+ const Stmt &Stm;
+ ASTContext &Context;
+ Memoized &Memorized;
+ };
+
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
- : Stm(Stm), Context(Context) {}
+ : Memorized(), A(Stm, Context, Memorized) {}
bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
- const Stmt *findMutation(const Expr *Exp);
- const Stmt *findMutation(const Decl *Dec);
+ const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); }
+ const Stmt *findMutation(const Decl *Dec) { return A.findMutation(Dec); }
bool isPointeeMutated(const Expr *Exp) {
return findPointeeMutation(Exp) != nullptr;
@@ -36,49 +94,40 @@ public:
bool isPointeeMutated(const Decl *Dec) {
return findPointeeMutation(Dec) != nullptr;
}
- const Stmt *findPointeeMutation(const Expr *Exp);
- const Stmt *findPointeeMutation(const Decl *Dec);
+ const Stmt *findPointeeMutation(const Expr *Exp) {
+ return A.findPointeeMutation(Exp);
+ }
+ const Stmt *findPointeeMutation(const Decl *Dec) {
+ return A.findPointeeMutation(Dec);
+ }
+
+ static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
+ ASTContext &Context) {
+ return Analyzer::isUnevaluated(Smt, Stm, Context);
+ }
private:
- using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
- using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
-
- const Stmt *findMutationMemoized(const Expr *Exp,
- llvm::ArrayRef<MutationFinder> Finders,
- ResultMap &MemoizedResults);
- const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
-
- bool isUnevaluated(const Expr *Exp);
-
- const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
- const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
- const Stmt *
- findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
- const Stmt *
- findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
-
- const Stmt *findDirectMutation(const Expr *Exp);
- const Stmt *findMemberMutation(const Expr *Exp);
- const Stmt *findArrayElementMutation(const Expr *Exp);
- const Stmt *findCastMutation(const Expr *Exp);
- const Stmt *findRangeLoopMutation(const Expr *Exp);
- const Stmt *findReferenceMutation(const Expr *Exp);
- const Stmt *findFunctionArgMutation(const Expr *Exp);
-
- const Stmt &Stm;
- ASTContext &Context;
- llvm::DenseMap<const FunctionDecl *,
- std::unique_ptr<FunctionParmMutationAnalyzer>>
- FuncParmAnalyzer;
- ResultMap Results;
- ResultMap PointeeResults;
+ Memoized Memorized;
+ Analyzer A;
};
// A convenient wrapper around ExprMutationAnalyzer for analyzing function
// params.
class FunctionParmMutationAnalyzer {
public:
- FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context);
+ static FunctionParmMutationAnalyzer *
+ getFunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context,
+ ExprMutationAnalyzer::Memoized &Memorized) {
+ auto it = Memorized.FuncParmAnalyzer.find(&Func);
+ if (it == Memorized.FuncParmAnalyzer.end())
+ it =
+ Memorized.FuncParmAnalyzer
+ .try_emplace(&Func, std::unique_ptr<FunctionParmMutationAnalyzer>(
+ new FunctionParmMutationAnalyzer(
+ Func, Context, Memorized)))
+ .first;
+ return it->getSecond().get();
+ }
bool isMutated(const ParmVarDecl *Parm) {
return findMutation(Parm) != nullptr;
@@ -86,8 +135,11 @@ public:
const Stmt *findMutation(const ParmVarDecl *Parm);
private:
- ExprMutationAnalyzer BodyAnalyzer;
+ ExprMutationAnalyzer::Analyzer BodyAnalyzer;
llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results;
+
+ FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context,
+ ExprMutationAnalyzer::Memoized &Memorized);
};
} // namespace clang