File indexing completed on 2026-05-10 08:37:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H
0014 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H
0015
0016 #include "clang/AST/Type.h"
0017 #include "clang/Basic/LLVM.h"
0018 #include "llvm/ADT/FoldingSet.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/iterator_range.h"
0021 #include <cassert>
0022
0023 namespace clang {
0024 namespace ento {
0025
0026 class MemRegion;
0027
0028 using SymbolID = unsigned;
0029
0030
0031
0032 class SymExpr : public llvm::FoldingSetNode {
0033 virtual void anchor();
0034
0035 public:
0036 enum Kind {
0037 #define SYMBOL(Id, Parent) Id##Kind,
0038 #define SYMBOL_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
0039 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
0040 };
0041
0042 private:
0043 Kind K;
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 const SymbolID Sym;
0054
0055 protected:
0056 SymExpr(Kind k, SymbolID Sym) : K(k), Sym(Sym) {}
0057
0058 static bool isValidTypeForSymbol(QualType T) {
0059
0060
0061 return !T.isNull() && !T->isVoidType();
0062 }
0063
0064 mutable unsigned Complexity = 0;
0065
0066 public:
0067 virtual ~SymExpr() = default;
0068
0069 Kind getKind() const { return K; }
0070
0071
0072
0073
0074
0075
0076
0077 SymbolID getSymbolID() const { return Sym; }
0078
0079 virtual void dump() const;
0080
0081 virtual void dumpToStream(raw_ostream &os) const {}
0082
0083 virtual QualType getType() const = 0;
0084 virtual void Profile(llvm::FoldingSetNodeID &profile) = 0;
0085
0086
0087
0088
0089
0090
0091 class symbol_iterator {
0092 SmallVector<const SymExpr *, 5> itr;
0093
0094 void expand();
0095
0096 public:
0097 symbol_iterator() = default;
0098 symbol_iterator(const SymExpr *SE);
0099
0100 symbol_iterator &operator++();
0101 const SymExpr *operator*();
0102
0103 bool operator==(const symbol_iterator &X) const;
0104 bool operator!=(const symbol_iterator &X) const;
0105 };
0106
0107 llvm::iterator_range<symbol_iterator> symbols() const {
0108 return llvm::make_range(symbol_iterator(this), symbol_iterator());
0109 }
0110
0111 virtual unsigned computeComplexity() const = 0;
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 virtual const MemRegion *getOriginRegion() const { return nullptr; }
0125 };
0126
0127 inline raw_ostream &operator<<(raw_ostream &os,
0128 const clang::ento::SymExpr *SE) {
0129 SE->dumpToStream(os);
0130 return os;
0131 }
0132
0133 using SymbolRef = const SymExpr *;
0134 using SymbolRefSmallVectorTy = SmallVector<SymbolRef, 2>;
0135
0136
0137
0138 class SymbolData : public SymExpr {
0139 void anchor() override;
0140
0141 protected:
0142 SymbolData(Kind k, SymbolID sym) : SymExpr(k, sym) { assert(classof(this)); }
0143
0144 public:
0145 ~SymbolData() override = default;
0146
0147
0148 virtual StringRef getKindStr() const = 0;
0149
0150 unsigned computeComplexity() const override {
0151 return 1;
0152 };
0153
0154
0155 static inline bool classof(const SymExpr *SE) {
0156 Kind k = SE->getKind();
0157 return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS;
0158 }
0159 };
0160
0161 }
0162 }
0163
0164 #endif