clang  19.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 
15 namespace clang {
16 
17 class FunctionParmMutationAnalyzer;
18 
19 /// Analyzes whether any mutative operations are applied to an expression within
20 /// a given statement.
23 
24 public:
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  static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
51  ASTContext &Context);
52 
53  private:
54  using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
55 
56  const Stmt *findMutationMemoized(const Expr *Exp,
58  Memoized::ResultMap &MemoizedResults);
59  const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
60 
61  bool isUnevaluated(const Expr *Exp);
62 
63  const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
64  const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
65  const Stmt *
66  findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
67  const Stmt *
68  findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
69 
70  const Stmt *findDirectMutation(const Expr *Exp);
71  const Stmt *findMemberMutation(const Expr *Exp);
72  const Stmt *findArrayElementMutation(const Expr *Exp);
73  const Stmt *findCastMutation(const Expr *Exp);
74  const Stmt *findRangeLoopMutation(const Expr *Exp);
75  const Stmt *findReferenceMutation(const Expr *Exp);
76  const Stmt *findFunctionArgMutation(const Expr *Exp);
77 
78  const Stmt &Stm;
79  ASTContext &Context;
80  Memoized &Memorized;
81  };
82 
83  ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
84  : Memorized(), A(Stm, Context, Memorized) {}
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 
104  static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
105  ASTContext &Context) {
106  return Analyzer::isUnevaluated(Smt, Stm, Context);
107  }
108 
109 private:
110  Memoized Memorized;
111  Analyzer A;
112 };
113 
114 // A convenient wrapper around ExprMutationAnalyzer for analyzing function
115 // params.
117 public:
120  ExprMutationAnalyzer::Memoized &Memorized) {
121  auto it = Memorized.FuncParmAnalyzer.find(&Func);
122  if (it == Memorized.FuncParmAnalyzer.end())
123  it =
124  Memorized.FuncParmAnalyzer
125  .try_emplace(&Func, std::unique_ptr<FunctionParmMutationAnalyzer>(
127  Func, Context, Memorized)))
128  .first;
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 
137 private:
138  ExprMutationAnalyzer::Analyzer BodyAnalyzer;
139  llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results;
140 
142  ExprMutationAnalyzer::Memoized &Memorized);
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:185
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 Decl *Dec)
const Stmt * findMutation(const Expr *Exp)
bool isMutated(const Decl *Dec)
const Stmt * findPointeeMutation(const Decl *Dec)
bool isPointeeMutated(const Expr *Exp)
bool isMutated(const Expr *Exp)
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
bool isPointeeMutated(const Decl *Dec)
static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm, ASTContext &Context)
const Stmt * findPointeeMutation(const Expr *Exp)
This represents one expression.
Definition: Expr.h:110
Represents a function declaration or definition.
Definition: Decl.h:1972
bool isMutated(const ParmVarDecl *Parm)
const Stmt * findMutation(const ParmVarDecl *Parm)
static FunctionParmMutationAnalyzer * getFunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context, ExprMutationAnalyzer::Memoized &Memorized)
Represents a parameter to a function.
Definition: Decl.h:1762
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)
static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm, ASTContext &Context)
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