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