clang  3.9.0
ProgramStateTrait.h
Go to the documentation of this file.
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_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
19 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
20 
21 #include "llvm/Support/Allocator.h"
22 #include "llvm/Support/DataTypes.h"
23 
24 namespace llvm {
25  template <typename K, typename D, typename I> class ImmutableMap;
26  template <typename K, typename I> class ImmutableSet;
27  template <typename T> class ImmutableList;
28  template <typename T> class ImmutableListImpl;
29 }
30 
31 namespace clang {
32 
33 namespace ento {
34  template <typename T> struct ProgramStatePartialTrait;
35 
36  /// Declares a program state trait for type \p Type called \p Name, and
37  /// introduce a typedef named \c NameTy.
38  /// The macro should not be used inside namespaces, or for traits that must
39  /// be accessible from more than one translation unit.
40  #define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
41  namespace { \
42  class Name {}; \
43  typedef Type Name ## Ty; \
44  } \
45  namespace clang { \
46  namespace ento { \
47  template <> \
48  struct ProgramStateTrait<Name> \
49  : public ProgramStatePartialTrait<Name ## Ty> { \
50  static void *GDMIndex() { static int Index; return &Index; } \
51  }; \
52  } \
53  }
54 
55 
56  // Partial-specialization for ImmutableMap.
57 
58  template <typename Key, typename Data, typename Info>
59  struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
61  typedef typename data_type::Factory& context_type;
62  typedef Key key_type;
63  typedef Data value_type;
64  typedef const value_type* lookup_type;
65 
66  static inline data_type MakeData(void *const* p) {
67  return p ? data_type((typename data_type::TreeTy*) *p)
68  : data_type(nullptr);
69  }
70  static inline void *MakeVoidPtr(data_type B) {
71  return B.getRoot();
72  }
74  return B.lookup(K);
75  }
77  return F.add(B, K, E);
78  }
79 
81  return F.remove(B, K);
82  }
83 
84  static inline context_type MakeContext(void *p) {
85  return *((typename data_type::Factory*) p);
86  }
87 
88  static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
89  return new typename data_type::Factory(Alloc);
90  }
91 
92  static void DeleteContext(void *Ctx) {
93  delete (typename data_type::Factory*) Ctx;
94  }
95  };
96 
97  /// Helper for registering a map trait.
98  ///
99  /// If the map type were written directly in the invocation of
100  /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
101  /// would be treated as a macro argument separator, which is wrong.
102  /// This allows the user to specify a map type in a way that the preprocessor
103  /// can deal with.
104  #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
105 
106 
107  // Partial-specialization for ImmutableSet.
108 
109  template <typename Key, typename Info>
110  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
112  typedef typename data_type::Factory& context_type;
113  typedef Key key_type;
114 
115  static inline data_type MakeData(void *const* p) {
116  return p ? data_type((typename data_type::TreeTy*) *p)
117  : data_type(nullptr);
118  }
119 
120  static inline void *MakeVoidPtr(data_type B) {
121  return B.getRoot();
122  }
123 
125  return F.add(B, K);
126  }
127 
129  return F.remove(B, K);
130  }
131 
132  static bool Contains(data_type B, key_type K) {
133  return B.contains(K);
134  }
135 
136  static inline context_type MakeContext(void *p) {
137  return *((typename data_type::Factory*) p);
138  }
139 
140  static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
141  return new typename data_type::Factory(Alloc);
142  }
143 
144  static void DeleteContext(void *Ctx) {
145  delete (typename data_type::Factory*) Ctx;
146  }
147  };
148 
149 
150  // Partial-specialization for ImmutableList.
151 
152  template <typename T>
153  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
155  typedef T key_type;
156  typedef typename data_type::Factory& context_type;
157 
159  return F.add(K, L);
160  }
161 
162  static bool Contains(data_type L, key_type K) {
163  return L.contains(K);
164  }
165 
166  static inline data_type MakeData(void *const* p) {
167  return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
168  : data_type(nullptr);
169  }
170 
171  static inline void *MakeVoidPtr(data_type D) {
172  return const_cast<llvm::ImmutableListImpl<T> *>(D.getInternalPointer());
173  }
174 
175  static inline context_type MakeContext(void *p) {
176  return *((typename data_type::Factory*) p);
177  }
178 
179  static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
180  return new typename data_type::Factory(Alloc);
181  }
182 
183  static void DeleteContext(void *Ctx) {
184  delete (typename data_type::Factory*) Ctx;
185  }
186  };
187 
188 
189  // Partial specialization for bool.
190  template <> struct ProgramStatePartialTrait<bool> {
191  typedef bool data_type;
192 
193  static inline data_type MakeData(void *const* p) {
194  return p ? (data_type) (uintptr_t) *p
195  : data_type();
196  }
197  static inline void *MakeVoidPtr(data_type d) {
198  return (void*) (uintptr_t) d;
199  }
200  };
201 
202  // Partial specialization for unsigned.
203  template <> struct ProgramStatePartialTrait<unsigned> {
204  typedef unsigned data_type;
205 
206  static inline data_type MakeData(void *const* p) {
207  return p ? (data_type) (uintptr_t) *p
208  : data_type();
209  }
210  static inline void *MakeVoidPtr(data_type d) {
211  return (void*) (uintptr_t) d;
212  }
213  };
214 
215  // Partial specialization for void*.
216  template <> struct ProgramStatePartialTrait<void*> {
217  typedef void *data_type;
218 
219  static inline data_type MakeData(void *const* p) {
220  return p ? *p
221  : data_type();
222  }
223  static inline void *MakeVoidPtr(data_type d) {
224  return d;
225  }
226  };
227 
228  // Partial specialization for const void *.
229  template <> struct ProgramStatePartialTrait<const void *> {
230  typedef const void *data_type;
231 
232  static inline data_type MakeData(void * const *p) {
233  return p ? *p : data_type();
234  }
235 
236  static inline void *MakeVoidPtr(data_type d) {
237  return const_cast<void *>(d);
238  }
239  };
240 
241 } // end ento namespace
242 
243 } // end clang namespace
244 
245 #endif
static data_type Add(data_type L, key_type K, context_type F)
static void * CreateContext(llvm::BumpPtrAllocator &Alloc)
static data_type Remove(data_type B, key_type K, context_type F)
#define bool
Definition: stdbool.h:31
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Definition: opencl-c.h:75
static data_type MakeData(void *const *p)
static data_type Set(data_type B, key_type K, value_type E, context_type F)
static data_type Remove(data_type B, key_type K, context_type F)
detail::InMemoryDirectory::const_iterator E
static data_type Add(data_type B, key_type K, context_type F)