ProgramStateTrait.h revision bdc691f1d61765dd806d5ae3b75ae004f676a7c9
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) { 170bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose return const_cast<llvm::ImmutableListImpl<T> *>(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 226bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose // Partial specialization for const void *. 227bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose template <> struct ProgramStatePartialTrait<const void *> { 228bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose typedef const void *data_type; 229bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose 230bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose static inline data_type MakeData(void * const *p) { 231bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose return p ? *p : data_type(); 232bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose } 233bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose 234bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose static inline void *MakeVoidPtr(data_type d) { 235bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose return const_cast<void *>(d); 236bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose } 237bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose }; 238bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose 239bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose} // end ento namespace 240ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 241ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end clang namespace 242ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 243ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#endif 244