clang  6.0.0svn
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  }
73  static lookup_type Lookup(data_type B, key_type K) {
74  return B.lookup(K);
75  }
76  static data_type Set(data_type B, key_type K, value_type E,context_type F){
77  return F.add(B, K, E);
78  }
79 
80  static data_type Remove(data_type B, key_type K, context_type F) {
81  return F.remove(B, K);
82  }
83 
84  static bool Contains(data_type B, key_type K) {
85  return B.contains(K);
86  }
87 
88  static inline context_type MakeContext(void *p) {
89  return *((typename data_type::Factory*) p);
90  }
91 
92  static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
93  return new typename data_type::Factory(Alloc);
94  }
95 
96  static void DeleteContext(void *Ctx) {
97  delete (typename data_type::Factory*) Ctx;
98  }
99  };
100 
101  /// Helper for registering a map trait.
102  ///
103  /// If the map type were written directly in the invocation of
104  /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
105  /// would be treated as a macro argument separator, which is wrong.
106  /// This allows the user to specify a map type in a way that the preprocessor
107  /// can deal with.
108  #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
109 
110 
111  // Partial-specialization for ImmutableSet.
112 
113  template <typename Key, typename Info>
114  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
116  typedef typename data_type::Factory& context_type;
117  typedef Key key_type;
118 
119  static inline data_type MakeData(void *const* p) {
120  return p ? data_type((typename data_type::TreeTy*) *p)
121  : data_type(nullptr);
122  }
123 
124  static inline void *MakeVoidPtr(data_type B) {
125  return B.getRoot();
126  }
127 
128  static data_type Add(data_type B, key_type K, context_type F) {
129  return F.add(B, K);
130  }
131 
132  static data_type Remove(data_type B, key_type K, context_type F) {
133  return F.remove(B, K);
134  }
135 
136  static bool Contains(data_type B, key_type K) {
137  return B.contains(K);
138  }
139 
140  static inline context_type MakeContext(void *p) {
141  return *((typename data_type::Factory*) p);
142  }
143 
144  static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
145  return new typename data_type::Factory(Alloc);
146  }
147 
148  static void DeleteContext(void *Ctx) {
149  delete (typename data_type::Factory*) Ctx;
150  }
151  };
152 
153 
154  // Partial-specialization for ImmutableList.
155 
156  template <typename T>
157  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
159  typedef T key_type;
160  typedef typename data_type::Factory& context_type;
161 
162  static data_type Add(data_type L, key_type K, context_type F) {
163  return F.add(K, L);
164  }
165 
166  static bool Contains(data_type L, key_type K) {
167  return L.contains(K);
168  }
169 
170  static inline data_type MakeData(void *const* p) {
171  return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
172  : data_type(nullptr);
173  }
174 
175  static inline void *MakeVoidPtr(data_type D) {
176  return const_cast<llvm::ImmutableListImpl<T> *>(D.getInternalPointer());
177  }
178 
179  static inline context_type MakeContext(void *p) {
180  return *((typename data_type::Factory*) p);
181  }
182 
183  static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
184  return new typename data_type::Factory(Alloc);
185  }
186 
187  static void DeleteContext(void *Ctx) {
188  delete (typename data_type::Factory*) Ctx;
189  }
190  };
191 
192 
193  // Partial specialization for bool.
194  template <> struct ProgramStatePartialTrait<bool> {
195  typedef bool data_type;
196 
197  static inline data_type MakeData(void *const* p) {
198  return p ? (data_type) (uintptr_t) *p
199  : data_type();
200  }
201  static inline void *MakeVoidPtr(data_type d) {
202  return (void*) (uintptr_t) d;
203  }
204  };
205 
206  // Partial specialization for unsigned.
207  template <> struct ProgramStatePartialTrait<unsigned> {
208  typedef unsigned data_type;
209 
210  static inline data_type MakeData(void *const* p) {
211  return p ? (data_type) (uintptr_t) *p
212  : data_type();
213  }
214  static inline void *MakeVoidPtr(data_type d) {
215  return (void*) (uintptr_t) d;
216  }
217  };
218 
219  // Partial specialization for void*.
220  template <> struct ProgramStatePartialTrait<void*> {
221  typedef void *data_type;
222 
223  static inline data_type MakeData(void *const* p) {
224  return p ? *p
225  : data_type();
226  }
227  static inline void *MakeVoidPtr(data_type d) {
228  return d;
229  }
230  };
231 
232  // Partial specialization for const void *.
233  template <> struct ProgramStatePartialTrait<const void *> {
234  typedef const void *data_type;
235 
236  static inline data_type MakeData(void * const *p) {
237  return p ? *p : data_type();
238  }
239 
240  static inline void *MakeVoidPtr(data_type d) {
241  return const_cast<void *>(d);
242  }
243  };
244 
245 } // end ento namespace
246 
247 } // end clang namespace
248 
249 #endif
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:26
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:82
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)
Dataflow Directional Tag Classes.
static data_type Add(data_type B, key_type K, context_type F)