ProgramStateTrait.h revision 40d8551890bc8454c4e0a28c9072c9c1d1dd588a
1ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*-
2ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
3ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//                     The LLVM Compiler Infrastructure
4ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
5ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek// This file is distributed under the University of Illinois Open Source
6ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek// License. See LICENSE.TXT for details.
7ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
8ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
9ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
10ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//  This file defines partial implementations of template specializations of
11ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//  the class ProgramStateTrait<>.  ProgramStateTrait<> is used by ProgramState
12af5f550de34525b27f0ff31dafce792caf8158b6Anna Zaks//  to implement set/get methods for manipulating a ProgramState's
13af5f550de34525b27f0ff31dafce792caf8158b6Anna Zaks//  generic data map.
14ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
15ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
16ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
17ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
18ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
19ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
20ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
21ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace llvm {
22ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  class BumpPtrAllocator;
23ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename K, typename D, typename I> class ImmutableMap;
24ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename K, typename I> class ImmutableSet;
25ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T> class ImmutableList;
26ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T> class ImmutableListImpl;
27ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
28ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
29ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace clang {
30ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
31ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace ento {
32ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T> struct ProgramStatePartialTrait;
33ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
34166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// Declares a program state trait for type \p Type called \p Name, and
35166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// introduce a typedef named \c NameTy.
36166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// The macro should not be used inside namespaces, or for traits that must
37166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// be accessible from more than one translation unit.
38166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  #define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
39166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    namespace { \
40166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      class Name {}; \
41166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      typedef Type Name ## Ty; \
42166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    } \
43166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    namespace clang { \
44166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    namespace ento { \
45166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      template <> \
46166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      struct ProgramStateTrait<Name> \
47166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose        : public ProgramStatePartialTrait<Name ## Ty> { \
48166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose        static void *GDMIndex() { static int Index; return &Index; } \
49166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      }; \
50166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    } \
51166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    }
52166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
53166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
54ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableMap.
55ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
56ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename Key, typename Data, typename Info>
57ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
58ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableMap<Key,Data,Info> data_type;
59ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
60ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef Key                               key_type;
61ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef Data                              value_type;
62ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef const value_type*                 lookup_type;
63ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
64ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
65ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
66ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
67ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type B) {
68ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.getRoot();
69ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
70ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static lookup_type Lookup(data_type B, key_type K) {
71ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.lookup(K);
72ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
73ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Set(data_type B, key_type K, value_type E,context_type F){
74ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(B, K, E);
75ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
76ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
77ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Remove(data_type B, key_type K, context_type F) {
78ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.remove(B, K);
79ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
80ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
81ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
82ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
83ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
84ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
85ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
86ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
87ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
88ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
89ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
90ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
91ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
92ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
93ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
9440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// Helper for registering a map trait.
9540d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  ///
9640d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// If the map type were written directly in the invocation of
9740d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
9840d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// would be treated as a macro argument separator, which is wrong.
9940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// This allows the user to specify a map type in a way that the preprocessor
10040d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// can deal with.
101166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
102166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
103ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
104ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableSet.
105ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
106ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename Key, typename Info>
107ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
108ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableSet<Key,Info>      data_type;
109ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
110ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef Key                               key_type;
111ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
112ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
113ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
114ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
115ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
116ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type B) {
117ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.getRoot();
118ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
119ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
120ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Add(data_type B, key_type K, context_type F) {
121ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(B, K);
122ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
123ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
124ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Remove(data_type B, key_type K, context_type F) {
125ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.remove(B, K);
126ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
127ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
128ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static bool Contains(data_type B, key_type K) {
129ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.contains(K);
130ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
131ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
132ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
133ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
134ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
135ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
136ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
137ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
138ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
139ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
140ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
141ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
142ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
143ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
144ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
145166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
146ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableList.
147ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
148ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
149ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
150ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableList<T>            data_type;
151ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef T                                 key_type;
152ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
153ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
154ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Add(data_type L, key_type K, context_type F) {
155ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(K, L);
156ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
157ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
158ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static bool Contains(data_type L, key_type K) {
159ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return L.contains(K);
160ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
161ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
162ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
163ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
164ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type(0);
165ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
166ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
167ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type D) {
168ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return  (void*) D.getInternalPointer();
169ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
170ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
171ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
172ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
173ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
174ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
175ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
176ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
177ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
178ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
179ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
180ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
181ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
182ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
183166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
184166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
185ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial specialization for bool.
186ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <> struct ProgramStatePartialTrait<bool> {
187ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef bool data_type;
188ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
189ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
190ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? (data_type) (uintptr_t) *p
191ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type();
192ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
193ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type d) {
194ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return (void*) (uintptr_t) d;
195ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
196ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
197ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
198ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial specialization for unsigned.
199ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <> struct ProgramStatePartialTrait<unsigned> {
200ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef unsigned data_type;
201ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
202ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
203ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? (data_type) (uintptr_t) *p
204ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type();
205ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
206ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type d) {
207ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return (void*) (uintptr_t) d;
208ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
209ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
2105903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
2115903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Partial specialization for void*.
2125903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  template <> struct ProgramStatePartialTrait<void*> {
2135903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    typedef void *data_type;
2145903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
2155903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    static inline data_type MakeData(void *const* p) {
2165903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      return p ? *p
2175903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks               : data_type();
2185903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    }
2195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    static inline void *MakeVoidPtr(data_type d) {
2205903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      return d;
2215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    }
2225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  };
2235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
224ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end GR namespace
225ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
226ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end clang namespace
227ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
228ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#endif
229