1 //== SymExpr.h - Management of Symbolic Values ------------------*- C++ -*--==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines SymExpr and SymbolData.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H
16 
17 #include "clang/AST/Type.h"
18 #include "llvm/ADT/FoldingSet.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/Support/raw_ostream.h"
21 
22 namespace clang {
23 namespace ento {
24 
25 /// \brief Symbolic value. These values used to capture symbolic execution of
26 /// the program.
27 class SymExpr : public llvm::FoldingSetNode {
28   virtual void anchor();
29 
30 public:
31   enum Kind {
32 #define SYMBOL(Id, Parent) Id##Kind,
33 #define SYMBOL_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
34 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
35   };
36 
37 private:
38   Kind K;
39 
40 protected:
41   SymExpr(Kind k) : K(k) {}
42 
43 public:
44   virtual ~SymExpr() {}
45 
46   Kind getKind() const { return K; }
47 
48   virtual void dump() const;
49 
50   virtual void dumpToStream(raw_ostream &os) const {}
51 
52   virtual QualType getType() const = 0;
53   virtual void Profile(llvm::FoldingSetNodeID &profile) = 0;
54 
55   /// \brief Iterator over symbols that the current symbol depends on.
56   ///
57   /// For SymbolData, it's the symbol itself; for expressions, it's the
58   /// expression symbol and all the operands in it. Note, SymbolDerived is
59   /// treated as SymbolData - the iterator will NOT visit the parent region.
60   class symbol_iterator {
61     SmallVector<const SymExpr *, 5> itr;
62     void expand();
63 
64   public:
65     symbol_iterator() {}
66     symbol_iterator(const SymExpr *SE);
67 
68     symbol_iterator &operator++();
69     const SymExpr *operator*();
70 
71     bool operator==(const symbol_iterator &X) const;
72     bool operator!=(const symbol_iterator &X) const;
73   };
74 
75   symbol_iterator symbol_begin() const { return symbol_iterator(this); }
76   static symbol_iterator symbol_end() { return symbol_iterator(); }
77 
78   unsigned computeComplexity() const;
79 };
80 
81 typedef const SymExpr *SymbolRef;
82 typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
83 
84 typedef unsigned SymbolID;
85 /// \brief A symbol representing data which can be stored in a memory location
86 /// (region).
87 class SymbolData : public SymExpr {
88   void anchor() override;
89   const SymbolID Sym;
90 
91 protected:
92   SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
93 
94 public:
95   ~SymbolData() override {}
96 
97   SymbolID getSymbolID() const { return Sym; }
98 
99   // Implement isa<T> support.
100   static inline bool classof(const SymExpr *SE) {
101     Kind k = SE->getKind();
102     return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS;
103   }
104 };
105 
106 } // namespace ento
107 } // namespace clang
108 
109 #endif
110