]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
Update clang to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.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_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> > {
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)
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> > {
115     typedef llvm::ImmutableSet<Key,Info>      data_type;
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> > {
158     typedef llvm::ImmutableList<T>            data_type;
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