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