-
Notifications
You must be signed in to change notification settings - Fork 9
/
AbstractDomain.h
142 lines (113 loc) · 4.33 KB
/
AbstractDomain.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef ABSTRACT_DOMAIN_H
#define ABSTRACT_DOMAIN_H
#include <iostream>
#include <vector>
#include <tr1/tuple>
#include "Counted.h"
#include "CompilerPortability.h"
#include "Utilities.h"
namespace absdomain {
namespace splt {
enum SplitTy {
FIRST = 0,
SECOND,
BOTH,
NONE,
TERMINATOR
};
} // End of the splt namespace
// T is the class that inherits the base class.
template <class T>
class AbstractDomain : public utils::pt::Counted {
public:
typedef typename boost::intrusive_ptr<T> DomainPtr;
typedef utils::Multimap<int, DomainPtr> CacheTy;
protected:
// Warning: Has to be initialized for every subtype!
static THREADLOCAL CacheTy* cache;
static void initCache() {
if (!cache) cache = new CacheTy();
}
AbstractDomain() {}
virtual ~AbstractDomain() {}
public:
static void shutdown() { delete cache; cache = 0; }
virtual DomainPtr join(T&) = 0;
virtual DomainPtr meet(T&) = 0;
virtual DomainPtr widen(T&)= 0;
//virtual DomainPtr rwiden(T&, T&, T&) = 0; // Restricted widening
virtual bool isTop() const = 0;
virtual bool isBot() const = 0;
bool isTopOrBottom() const { return isTop() || isBot(); }
static DomainPtr getBot() { return T::getBot(); }
static DomainPtr getTop() { return T::getTop(); }
// These are operators on the actual objects, i.e., strict
// (dis)equality among objects, ignoring the specific semantics of
// the abstract domain.
virtual bool operator==(const T&) const = 0;
virtual bool operator!=(const T&) const = 0;
// These are all operators over the abstract domain and might not be
// total.
virtual bool ai_equal(const T&) const = 0;
virtual bool ai_distinct(const T&) const = 0;
virtual bool operator<=(const T&) const = 0;
virtual bool operator<(const T&) const = 0;
virtual bool operator>=(const T&) const = 0;
virtual bool operator>(const T&) const = 0;
virtual bool subsumes(const T&) const = 0;
virtual bool subsumedBy(const T&) const = 0;
virtual bool withinBoundsOf(const T&) const= 0;
virtual bool isConstant() const = 0;
virtual bool isZero() const = 0;
virtual bool isTrue() const = 0;
virtual bool isFalse() const = 0;
virtual bool isMaybe() const {
return !isTrue() && !isFalse();
}
// These function should be implemented for interval-like
// domains, that can split longer intervals into smaller ones, like
// in the ASI analysis, see: Ramalingam, G., Field, J., and Tip, F.:
// Aggregate structure identification and its application to program
// analysis, In Proc. Symp. on Princ. of Prog. Lang., 1999.
typedef std::vector<DomainPtr> DomainPtrVec;
typedef std::vector<std::pair<DomainPtr, splt::SplitTy> >
DomainSplitVec;
virtual void split(const DomainPtrVec&, DomainSplitVec&) {}
virtual DomainPtr operator+(int offset) = 0;
virtual DomainPtr operator+(T&) = 0;
virtual DomainPtr operator*(T&) = 0;
virtual DomainPtr operator-() = 0;
virtual DomainPtr operator-(int offset) = 0;
virtual DomainPtr operator-(T&) = 0;
virtual DomainPtr operator++() = 0;
virtual DomainPtr operator--() = 0;
virtual DomainPtr operator|(T&) = 0;
virtual DomainPtr operator~() = 0;
virtual DomainPtr operator&(T&) = 0;
virtual DomainPtr operator^(T&) = 0;
virtual DomainPtr sdivide(T&) = 0;
virtual DomainPtr udivide(T&) = 0;
virtual DomainPtr smod(T&) = 0;
virtual DomainPtr umod(T&) = 0;
virtual DomainPtr lshift(T&) = 0;
virtual DomainPtr rshift(T&) = 0;
virtual DomainPtr arshift(T&) = 0;
virtual DomainPtr lrotate(T&) = 0;
virtual DomainPtr rrotate(T&) = 0;
virtual int getHash() const = 0;
virtual void print(std::ostream&) const = 0;
// Prints to std::cerr, for debugging. Definition in the cpp file,
// some debuggers have problems with inlined functions.
void print() const;
};
template <class T>
inline void AbstractDomain<T>::print() const {
print(std::cerr);
}
template <class T>
inline std::ostream& operator<<(std::ostream& os, const
AbstractDomain<T>& p) {
p.print(os); return os;
}
} // End of the absdomain namespace
#endif // ABSTRACT_DOMAIN_H