ProgramStateTrait.h revision 166d502d5367ceacd1313a33cac43b1048b8524d
1bbf1c514bd832bf1306fe3e87221fd78bbc306efGordon Henriksen//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*-
28ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//
38ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//                     The LLVM Compiler Infrastructure
48ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//
5234d529e582963ad4b5d83b911cd057fe99d1435Chris Lattner// This file is distributed under the University of Illinois Open Source
6234d529e582963ad4b5d83b911cd057fe99d1435Chris Lattner// License. See LICENSE.TXT for details.
78ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//
88ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//===----------------------------------------------------------------------===//
98ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//
108ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//  This file defines partial implementations of template specializations of
118ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//  the class ProgramStateTrait<>.  ProgramStateTrait<> is used by ProgramState
128ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//  to implement set/get methods for manipulating a ProgramState's
138ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//  generic data map.
148ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//
158ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//===----------------------------------------------------------------------===//
168ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
178ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
188ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
198ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
2046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen
218ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksennamespace llvm {
22da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  class BumpPtrAllocator;
23da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  template <typename K, typename D, typename I> class ImmutableMap;
246d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen  template <typename K, typename I> class ImmutableSet;
252618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen  template <typename T> class ImmutableList;
26da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  template <typename T> class ImmutableListImpl;
27da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen}
28da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen
29da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksennamespace clang {
30da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen
31da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksennamespace ento {
32da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  template <typename T> struct ProgramStatePartialTrait;
33da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen
34da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  /// Declares a program state trait for type \p Type called \p Name, and
35da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  /// introduce a typedef named \c NameTy.
36da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  /// The macro should not be used inside namespaces, or for traits that must
37da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  /// be accessible from more than one translation unit.
38da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  #define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
392e855e68d861224c9b61e2bc9cecad1536b1534bGordon Henriksen    namespace { \
40da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen      class Name {}; \
41da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen      typedef Type Name ## Ty; \
42da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen    } \
43da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen    namespace clang { \
44da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen    namespace ento { \
45da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen      template <> \
46da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen      struct ProgramStateTrait<Name> \
472e855e68d861224c9b61e2bc9cecad1536b1534bGordon Henriksen        : public ProgramStatePartialTrait<Name ## Ty> { \
48a9d059693b0bfdaa27bad71c2b0769beaf6ee7ddGordon Henriksen        static void *GDMIndex() { static int Index; return &Index; } \
49a9d059693b0bfdaa27bad71c2b0769beaf6ee7ddGordon Henriksen      }; \
50a9d059693b0bfdaa27bad71c2b0769beaf6ee7ddGordon Henriksen    } \
51da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen    }
528ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
534733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
544733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen  // Partial-specialization for ImmutableMap.
554733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
564733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen  template <typename Key, typename Data, typename Info>
574733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen  struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
584733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    typedef llvm::ImmutableMap<Key,Data,Info> data_type;
594733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    typedef typename data_type::Factory&      context_type;
604733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    typedef Key                               key_type;
614733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    typedef Data                              value_type;
624733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    typedef const value_type*                 lookup_type;
634733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
644733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static inline data_type MakeData(void *const* p) {
654733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
664733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    }
674733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static inline void *MakeVoidPtr(data_type B) {
684733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      return B.getRoot();
694733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    }
704733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static lookup_type Lookup(data_type B, key_type K) {
714733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      return B.lookup(K);
724733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    }
734733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static data_type Set(data_type B, key_type K, value_type E,context_type F){
744733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      return F.add(B, K, E);
75f440691a20eff24cf59ac14e10057234ae182dbeGordon Henriksen    }
764733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
774733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static data_type Remove(data_type B, key_type K, context_type F) {
784733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      return F.remove(B, K);
794733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    }
804733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
814733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static inline context_type MakeContext(void *p) {
824733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      return *((typename data_type::Factory*) p);
834733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    }
844733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
854733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
864733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      return new typename data_type::Factory(Alloc);
874733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    }
884733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
894733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    static void DeleteContext(void *Ctx) {
904733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen      delete (typename data_type::Factory*) Ctx;
914733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen    }
924733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen  };
934733be38930ae81716bba9ae75a8281bcb180634Gordon Henriksen
948ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen  /// Helper for REGISTER_MAP_WITH_PROGRAMSTATE.
955371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
965371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar
975371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  /// Declares an immutable map of type \p NameTy, suitable for placement into
985371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  /// the ProgramState.
995371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  /// The macro should not be used inside namespaces, or for traits that must
1005371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  /// be accessible from more than one translation unit.
1015371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \
1025371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar    REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \
1035371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar                                     CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value))
1045371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar
1055371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar
1065371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  // Partial-specialization for ImmutableSet.
1075371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar
1085371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  template <typename Key, typename Info>
1095371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
1105371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar    typedef llvm::ImmutableSet<Key,Info>      data_type;
1115371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar    typedef typename data_type::Factory&      context_type;
1125371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar    typedef Key                               key_type;
1138ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
1148ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static inline data_type MakeData(void *const* p) {
115263d989a719c1864862fc91f59193a6c2b55ca48Erick Tryzelaar      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
116263d989a719c1864862fc91f59193a6c2b55ca48Erick Tryzelaar    }
117263d989a719c1864862fc91f59193a6c2b55ca48Erick Tryzelaar
1188ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static inline void *MakeVoidPtr(data_type B) {
1198ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen      return B.getRoot();
1208ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    }
12146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen
12246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen    static data_type Add(data_type B, key_type K, context_type F) {
1238ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen      return F.add(B, K);
1248ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    }
1258ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
126a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    static data_type Remove(data_type B, key_type K, context_type F) {
127a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen      return F.remove(B, K);
128a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    }
129a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen
130a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    static bool Contains(data_type B, key_type K) {
131a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen      return B.contains(K);
132a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    }
133a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen
134a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    static inline context_type MakeContext(void *p) {
135a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen      return *((typename data_type::Factory*) p);
136a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    }
137a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen
138a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
139a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen      return new typename data_type::Factory(Alloc);
140a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    }
141a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen
142a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    static void DeleteContext(void *Ctx) {
143a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen      delete (typename data_type::Factory*) Ctx;
144a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen    }
145a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen  };
146a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen
147a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen  /// Declares an immutable list of type \p NameTy, suitable for placement into
1488ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen  /// the ProgramState.
14946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen  /// The macro should not be used inside namespaces, or for traits that must
15046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen  /// be accessible from more than one translation unit.
1518ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen  #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \
1528ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>)
1538ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
15446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen
15546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen  // Partial-specialization for ImmutableList.
15646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen
15746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen  template <typename T>
15846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
15946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen    typedef llvm::ImmutableList<T>            data_type;
160af59b105bb3f9a31f1812e470eb9db28a8a1b491Gordon Henriksen    typedef T                                 key_type;
161af59b105bb3f9a31f1812e470eb9db28a8a1b491Gordon Henriksen    typedef typename data_type::Factory&      context_type;
162af59b105bb3f9a31f1812e470eb9db28a8a1b491Gordon Henriksen
163af59b105bb3f9a31f1812e470eb9db28a8a1b491Gordon Henriksen    static data_type Add(data_type L, key_type K, context_type F) {
164af59b105bb3f9a31f1812e470eb9db28a8a1b491Gordon Henriksen      return F.add(K, L);
165af59b105bb3f9a31f1812e470eb9db28a8a1b491Gordon Henriksen    }
1668ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
1678ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static bool Contains(data_type L, key_type K) {
1688ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen      return L.contains(K);
169404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen    }
17046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen
17146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen    static inline data_type MakeData(void *const* p) {
1728ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
1738ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen               : data_type(0);
1745371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar    }
1755371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar
1765371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar    static inline void *MakeVoidPtr(data_type D) {
1775371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar      return  (void*) D.getInternalPointer();
1785371aa2a1c9a4eeecffdb9ab7b2175732e49475bErick Tryzelaar    }
1798ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
1808ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static inline context_type MakeContext(void *p) {
181b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar      return *((typename data_type::Factory*) p);
182b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    }
183b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
184b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
185b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar      return new typename data_type::Factory(Alloc);
186b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    }
187b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
188b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    static void DeleteContext(void *Ctx) {
189b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar      delete (typename data_type::Factory*) Ctx;
190b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    }
191b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  };
192b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
193b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  /// Declares an immutable list of type \p NameTy, suitable for placement into
194b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  /// the ProgramState.
195b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  /// The macro should not be used inside namespaces, or for traits that must
196b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  /// be accessible from more than one translation unit.
197b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \
198b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>)
199b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
200b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
201b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  // Partial specialization for bool.
202b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  template <> struct ProgramStatePartialTrait<bool> {
203b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    typedef bool data_type;
204b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
2058ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static inline data_type MakeData(void *const* p) {
206b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar      return p ? (data_type) (uintptr_t) *p
207b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar               : data_type();
208b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    }
2098ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static inline void *MakeVoidPtr(data_type d) {
2108ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen      return (void*) (uintptr_t) d;
2118ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    }
21246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen  };
21346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen
2148ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen  // Partial specialization for unsigned.
2158ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen  template <> struct ProgramStatePartialTrait<unsigned> {
2168ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    typedef unsigned data_type;
2178ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
218b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    static inline data_type MakeData(void *const* p) {
219b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar      return p ? (data_type) (uintptr_t) *p
220b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar               : data_type();
2218ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    }
2228ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static inline void *MakeVoidPtr(data_type d) {
223b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar      return (void*) (uintptr_t) d;
224b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    }
225b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  };
2268ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
2278ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen  // Partial specialization for void*.
228b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  template <> struct ProgramStatePartialTrait<void*> {
229b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    typedef void *data_type;
230b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
2318ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    static inline data_type MakeData(void *const* p) {
2328ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen      return p ? *p
233b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar               : data_type();
234b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    }
235b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar    static inline void *MakeVoidPtr(data_type d) {
2368ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen      return d;
2378ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen    }
238b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar  };
239b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar
240b02b87882788e57e180c6b903a37ced0db1ce828Erick Tryzelaar} // end GR namespace
2418ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
2428ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} // end clang namespace
2438ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen
2448ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#endif
245957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen