1343173Sdim//===---------- ExprMutationAnalyzer.h ------------------------------------===// 2343173Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343173Sdim// 7343173Sdim//===----------------------------------------------------------------------===// 8343173Sdim#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H 9343173Sdim#define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H 10343173Sdim 11343173Sdim#include <type_traits> 12343173Sdim 13343173Sdim#include "clang/AST/AST.h" 14343173Sdim#include "clang/ASTMatchers/ASTMatchers.h" 15343173Sdim#include "llvm/ADT/DenseMap.h" 16343173Sdim 17343173Sdimnamespace clang { 18343173Sdim 19343173Sdimclass FunctionParmMutationAnalyzer; 20343173Sdim 21343173Sdim/// Analyzes whether any mutative operations are applied to an expression within 22343173Sdim/// a given statement. 23343173Sdimclass ExprMutationAnalyzer { 24343173Sdimpublic: 25343173Sdim ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context) 26343173Sdim : Stm(Stm), Context(Context) {} 27343173Sdim 28343173Sdim bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; } 29343173Sdim bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; } 30343173Sdim const Stmt *findMutation(const Expr *Exp); 31343173Sdim const Stmt *findMutation(const Decl *Dec); 32343173Sdim 33343173Sdim bool isPointeeMutated(const Expr *Exp) { 34343173Sdim return findPointeeMutation(Exp) != nullptr; 35343173Sdim } 36343173Sdim bool isPointeeMutated(const Decl *Dec) { 37343173Sdim return findPointeeMutation(Dec) != nullptr; 38343173Sdim } 39343173Sdim const Stmt *findPointeeMutation(const Expr *Exp); 40343173Sdim const Stmt *findPointeeMutation(const Decl *Dec); 41343173Sdim 42343173Sdimprivate: 43343173Sdim using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *); 44343173Sdim using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>; 45343173Sdim 46343173Sdim const Stmt *findMutationMemoized(const Expr *Exp, 47343173Sdim llvm::ArrayRef<MutationFinder> Finders, 48343173Sdim ResultMap &MemoizedResults); 49343173Sdim const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder); 50343173Sdim 51343173Sdim bool isUnevaluated(const Expr *Exp); 52343173Sdim 53343173Sdim const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches); 54343173Sdim const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches); 55343173Sdim const Stmt * 56343173Sdim findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches); 57343173Sdim const Stmt * 58343173Sdim findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches); 59343173Sdim 60343173Sdim const Stmt *findDirectMutation(const Expr *Exp); 61343173Sdim const Stmt *findMemberMutation(const Expr *Exp); 62343173Sdim const Stmt *findArrayElementMutation(const Expr *Exp); 63343173Sdim const Stmt *findCastMutation(const Expr *Exp); 64343173Sdim const Stmt *findRangeLoopMutation(const Expr *Exp); 65343173Sdim const Stmt *findReferenceMutation(const Expr *Exp); 66343173Sdim const Stmt *findFunctionArgMutation(const Expr *Exp); 67343173Sdim 68343173Sdim const Stmt &Stm; 69343173Sdim ASTContext &Context; 70343173Sdim llvm::DenseMap<const FunctionDecl *, 71343173Sdim std::unique_ptr<FunctionParmMutationAnalyzer>> 72343173Sdim FuncParmAnalyzer; 73343173Sdim ResultMap Results; 74343173Sdim ResultMap PointeeResults; 75343173Sdim}; 76343173Sdim 77343173Sdim// A convenient wrapper around ExprMutationAnalyzer for analyzing function 78343173Sdim// params. 79343173Sdimclass FunctionParmMutationAnalyzer { 80343173Sdimpublic: 81343173Sdim FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context); 82343173Sdim 83343173Sdim bool isMutated(const ParmVarDecl *Parm) { 84343173Sdim return findMutation(Parm) != nullptr; 85343173Sdim } 86343173Sdim const Stmt *findMutation(const ParmVarDecl *Parm); 87343173Sdim 88343173Sdimprivate: 89343173Sdim ExprMutationAnalyzer BodyAnalyzer; 90343173Sdim llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results; 91343173Sdim}; 92343173Sdim 93343173Sdim} // namespace clang 94343173Sdim 95343173Sdim#endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H 96