Home | History | Annotate | Download | only in PathSensitive
      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 class MemRegion;
     26 
     27 /// \brief Symbolic value. These values used to capture symbolic execution of
     28 /// the program.
     29 class SymExpr : public llvm::FoldingSetNode {
     30   virtual void anchor();
     31 
     32 public:
     33   enum Kind {
     34 #define SYMBOL(Id, Parent) Id##Kind,
     35 #define SYMBOL_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
     36 #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
     37   };
     38 
     39 private:
     40   Kind K;
     41 
     42 protected:
     43   SymExpr(Kind k) : K(k) {}
     44 
     45 public:
     46   virtual ~SymExpr() {}
     47 
     48   Kind getKind() const { return K; }
     49 
     50   virtual void dump() const;
     51 
     52   virtual void dumpToStream(raw_ostream &os) const {}
     53 
     54   virtual QualType getType() const = 0;
     55   virtual void Profile(llvm::FoldingSetNodeID &profile) = 0;
     56 
     57   /// \brief Iterator over symbols that the current symbol depends on.
     58   ///
     59   /// For SymbolData, it's the symbol itself; for expressions, it's the
     60   /// expression symbol and all the operands in it. Note, SymbolDerived is
     61   /// treated as SymbolData - the iterator will NOT visit the parent region.
     62   class symbol_iterator {
     63     SmallVector<const SymExpr *, 5> itr;
     64     void expand();
     65 
     66   public:
     67     symbol_iterator() {}
     68     symbol_iterator(const SymExpr *SE);
     69 
     70     symbol_iterator &operator++();
     71     const SymExpr *operator*();
     72 
     73     bool operator==(const symbol_iterator &X) const;
     74     bool operator!=(const symbol_iterator &X) const;
     75   };
     76 
     77   symbol_iterator symbol_begin() const { return symbol_iterator(this); }
     78   static symbol_iterator symbol_end() { return symbol_iterator(); }
     79 
     80   unsigned computeComplexity() const;
     81 
     82   /// \brief Find the region from which this symbol originates.
     83   ///
     84   /// Whenever the symbol was constructed to denote an unknown value of
     85   /// a certain memory region, return this region. This method
     86   /// allows checkers to make decisions depending on the origin of the symbol.
     87   /// Symbol classes for which the origin region is known include
     88   /// SymbolRegionValue which denotes the value of the region before
     89   /// the beginning of the analysis, and SymbolDerived which denotes the value
     90   /// of a certain memory region after its super region (a memory space or
     91   /// a larger record region) is default-bound with a certain symbol.
     92   virtual const MemRegion *getOriginRegion() const { return nullptr; }
     93 };
     94 
     95 typedef const SymExpr *SymbolRef;
     96 typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
     97 
     98 typedef unsigned SymbolID;
     99 /// \brief A symbol representing data which can be stored in a memory location
    100 /// (region).
    101 class SymbolData : public SymExpr {
    102   void anchor() override;
    103   const SymbolID Sym;
    104 
    105 protected:
    106   SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
    107 
    108 public:
    109   ~SymbolData() override {}
    110 
    111   SymbolID getSymbolID() const { return Sym; }
    112 
    113   // Implement isa<T> support.
    114   static inline bool classof(const SymExpr *SE) {
    115     Kind k = SE->getKind();
    116     return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS;
    117   }
    118 };
    119 
    120 } // namespace ento
    121 } // namespace clang
    122 
    123 #endif
    124