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
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/Allocator.h"
229946fc735d7285f2195f89635370f534afd9877eDmitri Gribenko#include "llvm/Support/DataTypes.h"
239946fc735d7285f2195f89635370f534afd9877eDmitri Gribenko
24ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace llvm {
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) {
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return p ? data_type((typename data_type::TreeTy*) *p)
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               : data_type(nullptr);
69ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
70ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type B) {
71ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.getRoot();
72ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
73ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static lookup_type Lookup(data_type B, key_type K) {
74ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.lookup(K);
75ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
76ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Set(data_type B, key_type K, value_type E,context_type F){
77ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(B, K, E);
78ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
79ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
80ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Remove(data_type B, key_type K, context_type F) {
81ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.remove(B, K);
82ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
83ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
84ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
85ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
86ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
87ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
88ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
89ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
90ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
91ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
92ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
93ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
94ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
95ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
96ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
9740d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// Helper for registering a map trait.
9840d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  ///
9940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// If the map type were written directly in the invocation of
10040d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
10140d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// would be treated as a macro argument separator, which is wrong.
10240d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// This allows the user to specify a map type in a way that the preprocessor
10340d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose  /// can deal with.
104166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
105166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
106ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
107ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableSet.
108ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
109ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename Key, typename Info>
110ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
111ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableSet<Key,Info>      data_type;
112ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
113ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef Key                               key_type;
114ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
115ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return p ? data_type((typename data_type::TreeTy*) *p)
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               : data_type(nullptr);
118ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
119ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
120ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type B) {
121ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.getRoot();
122ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
123ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
124ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Add(data_type B, key_type K, context_type F) {
125ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(B, K);
126ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
127ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
128ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Remove(data_type B, key_type K, context_type F) {
129ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.remove(B, K);
130ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
131ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
132ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static bool Contains(data_type B, key_type K) {
133ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return B.contains(K);
134ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
135ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
136ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
137ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
138ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
139ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
140ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
141ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
142ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
143ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
144ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
145ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
146ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
147ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
148ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
149166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
150ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial-specialization for ImmutableList.
151ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
152ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
153ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
154ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef llvm::ImmutableList<T>            data_type;
155ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef T                                 key_type;
156ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef typename data_type::Factory&      context_type;
157ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
158ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static data_type Add(data_type L, key_type K, context_type F) {
159ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return F.add(K, L);
160ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
161ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
162ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static bool Contains(data_type L, key_type K) {
163ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return L.contains(K);
164ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
165ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
166ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
167ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               : data_type(nullptr);
169ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
170ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
171ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type D) {
172bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose      return const_cast<llvm::ImmutableListImpl<T> *>(D.getInternalPointer());
173ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
174ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
175ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline context_type MakeContext(void *p) {
176ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return *((typename data_type::Factory*) p);
177ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
178ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
179ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
180ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return new typename data_type::Factory(Alloc);
181ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
182ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
183ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static void DeleteContext(void *Ctx) {
184ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      delete (typename data_type::Factory*) Ctx;
185ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
186ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
187166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
188166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose
189ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial specialization for bool.
190ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <> struct ProgramStatePartialTrait<bool> {
191ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef bool data_type;
192ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
193ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
194ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? (data_type) (uintptr_t) *p
195ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type();
196ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
197ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type d) {
198ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return (void*) (uintptr_t) d;
199ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
200ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
201ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
202ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Partial specialization for unsigned.
203ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <> struct ProgramStatePartialTrait<unsigned> {
204ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    typedef unsigned data_type;
205ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
206ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline data_type MakeData(void *const* p) {
207ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return p ? (data_type) (uintptr_t) *p
208ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek               : data_type();
209ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
210ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    static inline void *MakeVoidPtr(data_type d) {
211ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      return (void*) (uintptr_t) d;
212ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
213ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
2145903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
2155903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Partial specialization for void*.
2165903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  template <> struct ProgramStatePartialTrait<void*> {
2175903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    typedef void *data_type;
2185903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
2195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    static inline data_type MakeData(void *const* p) {
2205903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      return p ? *p
2215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks               : data_type();
2225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    }
2235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    static inline void *MakeVoidPtr(data_type d) {
2245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      return d;
2255903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    }
2265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  };
2275903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
228bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose  // Partial specialization for const void *.
229bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose  template <> struct ProgramStatePartialTrait<const void *> {
230bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose    typedef const void *data_type;
231bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose
232bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose    static inline data_type MakeData(void * const *p) {
233bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose      return p ? *p : data_type();
234bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose    }
235bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose
236bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose    static inline void *MakeVoidPtr(data_type d) {
237bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose      return const_cast<void *>(d);
238bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose    }
239bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose  };
240bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose
241bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose} // end ento namespace
242ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
243ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end clang namespace
244ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
245ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#endif
246