1 //===---------- ExprMutationAnalyzer.h ------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
10 #define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
12 #include <type_traits>
14 #include "clang/AST/AST.h"
15 #include "clang/ASTMatchers/ASTMatchers.h"
16 #include "llvm/ADT/DenseMap.h"
20 class FunctionParmMutationAnalyzer;
22 /// Analyzes whether any mutative operations are applied to an expression within
23 /// a given statement.
24 class ExprMutationAnalyzer {
26 ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
27 : Stm(Stm), Context(Context) {}
29 bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
30 bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
31 const Stmt *findMutation(const Expr *Exp);
32 const Stmt *findMutation(const Decl *Dec);
34 bool isPointeeMutated(const Expr *Exp) {
35 return findPointeeMutation(Exp) != nullptr;
37 bool isPointeeMutated(const Decl *Dec) {
38 return findPointeeMutation(Dec) != nullptr;
40 const Stmt *findPointeeMutation(const Expr *Exp);
41 const Stmt *findPointeeMutation(const Decl *Dec);
44 using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
45 using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
47 const Stmt *findMutationMemoized(const Expr *Exp,
48 llvm::ArrayRef<MutationFinder> Finders,
49 ResultMap &MemoizedResults);
50 const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
52 bool isUnevaluated(const Expr *Exp);
54 const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
55 const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
57 findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
59 findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
61 const Stmt *findDirectMutation(const Expr *Exp);
62 const Stmt *findMemberMutation(const Expr *Exp);
63 const Stmt *findArrayElementMutation(const Expr *Exp);
64 const Stmt *findCastMutation(const Expr *Exp);
65 const Stmt *findRangeLoopMutation(const Expr *Exp);
66 const Stmt *findReferenceMutation(const Expr *Exp);
67 const Stmt *findFunctionArgMutation(const Expr *Exp);
71 llvm::DenseMap<const FunctionDecl *,
72 std::unique_ptr<FunctionParmMutationAnalyzer>>
75 ResultMap PointeeResults;
78 // A convenient wrapper around ExprMutationAnalyzer for analyzing function
80 class FunctionParmMutationAnalyzer {
82 FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context);
84 bool isMutated(const ParmVarDecl *Parm) {
85 return findMutation(Parm) != nullptr;
87 const Stmt *findMutation(const ParmVarDecl *Parm);
90 ExprMutationAnalyzer BodyAnalyzer;
91 llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results;
96 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H