ProgramStateTrait.h revision 9946fc735d7285f2195f89635370f534afd9877e
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
219946fc735d7285f2195f89635370f534afd9877eDmitri Gribenko#include "llvm/Support/DataTypes.h"
229946fc735d7285f2195f89635370f534afd9877eDmitri Gribenko
23ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace llvm {
24ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  class BumpPtrAllocator;
25ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename K, typename D, typename I> class ImmutableMap;
26ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename K, typename I> class ImmutableSet;
27ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T> class ImmutableList;
28ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T> class ImmutableListImpl;
29ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
30ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
31ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace clang {
32ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
33ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace ento {
34ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T> struct ProgramStatePartialTrait;
35ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
36166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// Declares a program state trait for type \p Type called \p Name, and
37166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// introduce a typedef named \c NameTy.
38166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// The macro should not be used inside namespaces, or for traits that must
39166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  /// be accessible from more than one translation unit.
40166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  #define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
41166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    namespace { \
42166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      class Name {}; \
43166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      typedef Type Name ## Ty; \
44166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    } \
45166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    namespace clang { \
46166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    namespace ento { \
47166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      template <> \
48166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      struct ProgramStateTrait<Name> \
49166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose        : public ProgramStatePartialTrait<Name ## Ty> { \
50166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose        static void *GDMIndex() { static int Index; return &Index; } \
51166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose      }; \
52166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    } \
53166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose    }
54166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
55166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
56ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableMap.
57ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
58ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename Key, typename Data, typename Info>
59ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
60ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableMap<Key,Data,Info> data_type;
61ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
62ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef Key                               key_type;
63ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef Data                              value_type;
64ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef const value_type*                 lookup_type;
65ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
66ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
67ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
68ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
69ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type B) {
70ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.getRoot();
71ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
72ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static lookup_type Lookup(data_type B, key_type K) {
73ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.lookup(K);
74ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
75ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Set(data_type B, key_type K, value_type E,context_type F){
76ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(B, K, E);
77ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
78ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
79ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Remove(data_type B, key_type K, context_type F) {
80ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.remove(B, K);
81ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
82ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
83ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
84ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
85ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
86ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
87ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
88ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
89ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
90ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
91ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
92ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
93ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
94ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
95ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
9640d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// Helper for registering a map trait.
9740d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  ///
9840d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// If the map type were written directly in the invocation of
9940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
10040d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// would be treated as a macro argument separator, which is wrong.
10140d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// This allows the user to specify a map type in a way that the preprocessor
10240d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// can deal with.
103166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
104166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
105ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
106ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableSet.
107ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
108ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename Key, typename Info>
109ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
110ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableSet<Key,Info>      data_type;
111ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
112ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef Key                               key_type;
113ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
114ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
115ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
116ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
117ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
118ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type B) {
119ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.getRoot();
120ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
121ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
122ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Add(data_type B, key_type K, context_type F) {
123ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(B, K);
124ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
125ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
126ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Remove(data_type B, key_type K, context_type F) {
127ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.remove(B, K);
128ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
129ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
130ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static bool Contains(data_type B, key_type K) {
131ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.contains(K);
132ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
133ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
134ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
135ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
136ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
137ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
138ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
139ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
140ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
141ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
142ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
143ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
144ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
145ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
146ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
147166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
148ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableList.
149ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
150ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
151ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
152ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableList<T>            data_type;
153ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef T                                 key_type;
154ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
155ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
156ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Add(data_type L, key_type K, context_type F) {
157ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(K, L);
158ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
159ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
160ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static bool Contains(data_type L, key_type K) {
161ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return L.contains(K);
162ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
163ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
164ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
165ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
166ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type(0);
167ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
168ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
169ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type D) {
170ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return  (void*) D.getInternalPointer();
171ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
172ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
173ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
174ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
175ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
176ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
177ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
178ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
179ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
180ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
181ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
182ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
183ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
184ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
185166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
186166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
187ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial specialization for bool.
188ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <> struct ProgramStatePartialTrait<bool> {
189ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef bool data_type;
190ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
191ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
192ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? (data_type) (uintptr_t) *p
193ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type();
194ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
195ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type d) {
196ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return (void*) (uintptr_t) d;
197ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
198ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
199ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
200ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial specialization for unsigned.
201ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <> struct ProgramStatePartialTrait<unsigned> {
202ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef unsigned data_type;
203ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
204ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
205ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? (data_type) (uintptr_t) *p
206ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type();
207ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
208ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type d) {
209ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return (void*) (uintptr_t) d;
210ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
211ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
2125903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
2135903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Partial specialization for void*.
2145903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  template <> struct ProgramStatePartialTrait<void*> {
2155903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    typedef void *data_type;
2165903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
2175903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    static inline data_type MakeData(void *const* p) {
2185903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      return p ? *p
2195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks               : data_type();
2205903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    }
2215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    static inline void *MakeVoidPtr(data_type d) {
2225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      return d;
2235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    }
2245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  };
2255903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
226ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end GR namespace
227ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
228ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end clang namespace
229ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
230ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#endif
231