1 //ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*- 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines partial implementations of template specializations of 11 // the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState 12 // to implement set/get methods for manipulating a ProgramState's 13 // generic data map. 14 // 15 //===----------------------------------------------------------------------===// 16 17 18 #ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H 19 #define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H 20 21 namespace llvm { 22 class BumpPtrAllocator; 23 template <typename K, typename D, typename I> class ImmutableMap; 24 template <typename K, typename I> class ImmutableSet; 25 template <typename T> class ImmutableList; 26 template <typename T> class ImmutableListImpl; 27 } 28 29 namespace clang { 30 31 namespace ento { 32 template <typename T> struct ProgramStatePartialTrait; 33 34 // Partial-specialization for ImmutableMap. 35 36 template <typename Key, typename Data, typename Info> 37 struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > { 38 typedef llvm::ImmutableMap<Key,Data,Info> data_type; 39 typedef typename data_type::Factory& context_type; 40 typedef Key key_type; 41 typedef Data value_type; 42 typedef const value_type* lookup_type; 43 44 static inline data_type MakeData(void *const* p) { 45 return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); 46 } 47 static inline void *MakeVoidPtr(data_type B) { 48 return B.getRoot(); 49 } 50 static lookup_type Lookup(data_type B, key_type K) { 51 return B.lookup(K); 52 } 53 static data_type Set(data_type B, key_type K, value_type E,context_type F){ 54 return F.add(B, K, E); 55 } 56 57 static data_type Remove(data_type B, key_type K, context_type F) { 58 return F.remove(B, K); 59 } 60 61 static inline context_type MakeContext(void *p) { 62 return *((typename data_type::Factory*) p); 63 } 64 65 static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 66 return new typename data_type::Factory(Alloc); 67 } 68 69 static void DeleteContext(void *Ctx) { 70 delete (typename data_type::Factory*) Ctx; 71 } 72 }; 73 74 75 // Partial-specialization for ImmutableSet. 76 77 template <typename Key, typename Info> 78 struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > { 79 typedef llvm::ImmutableSet<Key,Info> data_type; 80 typedef typename data_type::Factory& context_type; 81 typedef Key key_type; 82 83 static inline data_type MakeData(void *const* p) { 84 return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); 85 } 86 87 static inline void *MakeVoidPtr(data_type B) { 88 return B.getRoot(); 89 } 90 91 static data_type Add(data_type B, key_type K, context_type F) { 92 return F.add(B, K); 93 } 94 95 static data_type Remove(data_type B, key_type K, context_type F) { 96 return F.remove(B, K); 97 } 98 99 static bool Contains(data_type B, key_type K) { 100 return B.contains(K); 101 } 102 103 static inline context_type MakeContext(void *p) { 104 return *((typename data_type::Factory*) p); 105 } 106 107 static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 108 return new typename data_type::Factory(Alloc); 109 } 110 111 static void DeleteContext(void *Ctx) { 112 delete (typename data_type::Factory*) Ctx; 113 } 114 }; 115 116 // Partial-specialization for ImmutableList. 117 118 template <typename T> 119 struct ProgramStatePartialTrait< llvm::ImmutableList<T> > { 120 typedef llvm::ImmutableList<T> data_type; 121 typedef T key_type; 122 typedef typename data_type::Factory& context_type; 123 124 static data_type Add(data_type L, key_type K, context_type F) { 125 return F.add(K, L); 126 } 127 128 static bool Contains(data_type L, key_type K) { 129 return L.contains(K); 130 } 131 132 static inline data_type MakeData(void *const* p) { 133 return p ? data_type((const llvm::ImmutableListImpl<T>*) *p) 134 : data_type(0); 135 } 136 137 static inline void *MakeVoidPtr(data_type D) { 138 return (void*) D.getInternalPointer(); 139 } 140 141 static inline context_type MakeContext(void *p) { 142 return *((typename data_type::Factory*) p); 143 } 144 145 static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 146 return new typename data_type::Factory(Alloc); 147 } 148 149 static void DeleteContext(void *Ctx) { 150 delete (typename data_type::Factory*) Ctx; 151 } 152 }; 153 154 // Partial specialization for bool. 155 template <> struct ProgramStatePartialTrait<bool> { 156 typedef bool data_type; 157 158 static inline data_type MakeData(void *const* p) { 159 return p ? (data_type) (uintptr_t) *p 160 : data_type(); 161 } 162 static inline void *MakeVoidPtr(data_type d) { 163 return (void*) (uintptr_t) d; 164 } 165 }; 166 167 // Partial specialization for unsigned. 168 template <> struct ProgramStatePartialTrait<unsigned> { 169 typedef unsigned data_type; 170 171 static inline data_type MakeData(void *const* p) { 172 return p ? (data_type) (uintptr_t) *p 173 : data_type(); 174 } 175 static inline void *MakeVoidPtr(data_type d) { 176 return (void*) (uintptr_t) d; 177 } 178 }; 179 180 // Partial specialization for void*. 181 template <> struct ProgramStatePartialTrait<void*> { 182 typedef void *data_type; 183 184 static inline data_type MakeData(void *const* p) { 185 return p ? *p 186 : data_type(); 187 } 188 static inline void *MakeVoidPtr(data_type d) { 189 return d; 190 } 191 }; 192 193 } // end GR namespace 194 195 } // end clang namespace 196 197 #endif 198