File indexing completed on 2026-05-10 08:37:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
0014 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
0015
0016 #include "clang/Analysis/AnalysisDeclContext.h"
0017 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
0018 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0019 #include "llvm/ADT/ImmutableMap.h"
0020 #include <utility>
0021
0022 namespace clang {
0023
0024 class Stmt;
0025
0026 namespace ento {
0027
0028 class SValBuilder;
0029 class SymbolReaper;
0030
0031
0032
0033
0034
0035 class EnvironmentEntry : public std::pair<const Stmt *,
0036 const StackFrameContext *> {
0037 public:
0038 EnvironmentEntry(const Stmt *s, const LocationContext *L);
0039
0040 const Stmt *getStmt() const { return first; }
0041 const LocationContext *getLocationContext() const { return second; }
0042
0043
0044 static void Profile(llvm::FoldingSetNodeID &ID,
0045 const EnvironmentEntry &E) {
0046 ID.AddPointer(E.getStmt());
0047 ID.AddPointer(E.getLocationContext());
0048 }
0049
0050 void Profile(llvm::FoldingSetNodeID &ID) const {
0051 Profile(ID, *this);
0052 }
0053 };
0054
0055
0056 class Environment {
0057 private:
0058 friend class EnvironmentManager;
0059
0060 using BindingsTy = llvm::ImmutableMap<EnvironmentEntry, SVal>;
0061
0062 BindingsTy ExprBindings;
0063
0064 Environment(BindingsTy eb) : ExprBindings(eb) {}
0065
0066 SVal lookupExpr(const EnvironmentEntry &E) const;
0067
0068 public:
0069 using iterator = BindingsTy::iterator;
0070
0071 iterator begin() const { return ExprBindings.begin(); }
0072 iterator end() const { return ExprBindings.end(); }
0073
0074
0075
0076 SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const;
0077
0078
0079
0080 static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) {
0081 env->ExprBindings.Profile(ID);
0082 }
0083
0084
0085
0086 void Profile(llvm::FoldingSetNodeID& ID) const {
0087 Profile(ID, this);
0088 }
0089
0090 bool operator==(const Environment& RHS) const {
0091 return ExprBindings == RHS.ExprBindings;
0092 }
0093
0094 void printJson(raw_ostream &Out, const ASTContext &Ctx,
0095 const LocationContext *LCtx = nullptr, const char *NL = "\n",
0096 unsigned int Space = 0, bool IsDot = false) const;
0097 };
0098
0099 class EnvironmentManager {
0100 private:
0101 using FactoryTy = Environment::BindingsTy::Factory;
0102
0103 FactoryTy F;
0104
0105 public:
0106 EnvironmentManager(llvm::BumpPtrAllocator &Allocator) : F(Allocator) {}
0107
0108 Environment getInitialEnvironment() {
0109 return Environment(F.getEmptyMap());
0110 }
0111
0112
0113 Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V,
0114 bool Invalidate);
0115
0116 Environment removeDeadBindings(Environment Env,
0117 SymbolReaper &SymReaper,
0118 ProgramStateRef state);
0119 };
0120
0121 }
0122
0123 }
0124
0125 #endif