ProgramStateTrait.h revision 5903a373db3d27794c90b25687e0dd6adb0e497d
1//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- 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 partial implementations of template specializations of
11//  the class ProgramStateTrait<>.  ProgramStateTrait<> is used by ProgramState
12//  to implement set/get methods for manipulating a ProgramState's
13//  generic data map.
14//
15//===----------------------------------------------------------------------===//
16
17
18#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
19#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
20
21namespace llvm {
22  class BumpPtrAllocator;
23  template <typename K, typename D, typename I> class ImmutableMap;
24  template <typename K, typename I> class ImmutableSet;
25  template <typename T> class ImmutableList;
26  template <typename T> class ImmutableListImpl;
27}
28
29namespace clang {
30
31namespace ento {
32  template <typename T> struct ProgramStatePartialTrait;
33
34  // Partial-specialization for ImmutableMap.
35
36  template <typename Key, typename Data, typename Info>
37  struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
38    typedef llvm::ImmutableMap<Key,Data,Info> data_type;
39    typedef typename data_type::Factory&      context_type;
40    typedef Key                               key_type;
41    typedef Data                              value_type;
42    typedef const value_type*                 lookup_type;
43
44    static inline data_type MakeData(void *const* p) {
45      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
46    }
47    static inline void *MakeVoidPtr(data_type B) {
48      return B.getRoot();
49    }
50    static lookup_type Lookup(data_type B, key_type K) {
51      return B.lookup(K);
52    }
53    static data_type Set(data_type B, key_type K, value_type E,context_type F){
54      return F.add(B, K, E);
55    }
56
57    static data_type Remove(data_type B, key_type K, context_type F) {
58      return F.remove(B, K);
59    }
60
61    static inline context_type MakeContext(void *p) {
62      return *((typename data_type::Factory*) p);
63    }
64
65    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
66      return new typename data_type::Factory(Alloc);
67    }
68
69    static void DeleteContext(void *Ctx) {
70      delete (typename data_type::Factory*) Ctx;
71    }
72  };
73
74
75  // Partial-specialization for ImmutableSet.
76
77  template <typename Key, typename Info>
78  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
79    typedef llvm::ImmutableSet<Key,Info>      data_type;
80    typedef typename data_type::Factory&      context_type;
81    typedef Key                               key_type;
82
83    static inline data_type MakeData(void *const* p) {
84      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
85    }
86
87    static inline void *MakeVoidPtr(data_type B) {
88      return B.getRoot();
89    }
90
91    static data_type Add(data_type B, key_type K, context_type F) {
92      return F.add(B, K);
93    }
94
95    static data_type Remove(data_type B, key_type K, context_type F) {
96      return F.remove(B, K);
97    }
98
99    static bool Contains(data_type B, key_type K) {
100      return B.contains(K);
101    }
102
103    static inline context_type MakeContext(void *p) {
104      return *((typename data_type::Factory*) p);
105    }
106
107    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
108      return new typename data_type::Factory(Alloc);
109    }
110
111    static void DeleteContext(void *Ctx) {
112      delete (typename data_type::Factory*) Ctx;
113    }
114  };
115
116  // Partial-specialization for ImmutableList.
117
118  template <typename T>
119  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
120    typedef llvm::ImmutableList<T>            data_type;
121    typedef T                                 key_type;
122    typedef typename data_type::Factory&      context_type;
123
124    static data_type Add(data_type L, key_type K, context_type F) {
125      return F.add(K, L);
126    }
127
128    static bool Contains(data_type L, key_type K) {
129      return L.contains(K);
130    }
131
132    static inline data_type MakeData(void *const* p) {
133      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
134               : data_type(0);
135    }
136
137    static inline void *MakeVoidPtr(data_type D) {
138      return  (void*) D.getInternalPointer();
139    }
140
141    static inline context_type MakeContext(void *p) {
142      return *((typename data_type::Factory*) p);
143    }
144
145    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
146      return new typename data_type::Factory(Alloc);
147    }
148
149    static void DeleteContext(void *Ctx) {
150      delete (typename data_type::Factory*) Ctx;
151    }
152  };
153
154  // Partial specialization for bool.
155  template <> struct ProgramStatePartialTrait<bool> {
156    typedef bool data_type;
157
158    static inline data_type MakeData(void *const* p) {
159      return p ? (data_type) (uintptr_t) *p
160               : data_type();
161    }
162    static inline void *MakeVoidPtr(data_type d) {
163      return (void*) (uintptr_t) d;
164    }
165  };
166
167  // Partial specialization for unsigned.
168  template <> struct ProgramStatePartialTrait<unsigned> {
169    typedef unsigned data_type;
170
171    static inline data_type MakeData(void *const* p) {
172      return p ? (data_type) (uintptr_t) *p
173               : data_type();
174    }
175    static inline void *MakeVoidPtr(data_type d) {
176      return (void*) (uintptr_t) d;
177    }
178  };
179
180  // Partial specialization for void*.
181  template <> struct ProgramStatePartialTrait<void*> {
182    typedef void *data_type;
183
184    static inline data_type MakeData(void *const* p) {
185      return p ? *p
186               : data_type();
187    }
188    static inline void *MakeVoidPtr(data_type d) {
189      return d;
190    }
191  };
192
193} // end GR namespace
194
195} // end clang namespace
196
197#endif
198