ProgramStateTrait.h revision 5903a373db3d27794c90b25687e0dd6adb0e497d
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 21ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace llvm { 22ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek class BumpPtrAllocator; 23ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename K, typename D, typename I> class ImmutableMap; 24ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename K, typename I> class ImmutableSet; 25ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename T> class ImmutableList; 26ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename T> class ImmutableListImpl; 27ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} 28ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 29ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace clang { 30ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 31ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace ento { 32ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename T> struct ProgramStatePartialTrait; 33ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 34ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek // Partial-specialization for ImmutableMap. 35ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 36ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename Key, typename Data, typename Info> 37ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > { 38ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef llvm::ImmutableMap<Key,Data,Info> data_type; 39ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef typename data_type::Factory& context_type; 40ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef Key key_type; 41ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef Data value_type; 42ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef const value_type* lookup_type; 43ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 44ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline data_type MakeData(void *const* p) { 45ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); 46ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 47ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline void *MakeVoidPtr(data_type B) { 48ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return B.getRoot(); 49ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 50ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static lookup_type Lookup(data_type B, key_type K) { 51ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return B.lookup(K); 52ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 53ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static data_type Set(data_type B, key_type K, value_type E,context_type F){ 54ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return F.add(B, K, E); 55ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 56ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 57ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static data_type Remove(data_type B, key_type K, context_type F) { 58ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return F.remove(B, K); 59ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 60ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 61ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline context_type MakeContext(void *p) { 62ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return *((typename data_type::Factory*) p); 63ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 64ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 65ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 66ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return new typename data_type::Factory(Alloc); 67ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 68ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 69ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static void DeleteContext(void *Ctx) { 70ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek delete (typename data_type::Factory*) Ctx; 71ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 72ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek }; 73ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 74ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 75ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek // Partial-specialization for ImmutableSet. 76ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 77ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename Key, typename Info> 78ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > { 79ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef llvm::ImmutableSet<Key,Info> data_type; 80ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef typename data_type::Factory& context_type; 81ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef Key key_type; 82ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 83ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline data_type MakeData(void *const* p) { 84ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); 85ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 86ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 87ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline void *MakeVoidPtr(data_type B) { 88ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return B.getRoot(); 89ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 90ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 91ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static data_type Add(data_type B, key_type K, context_type F) { 92ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return F.add(B, K); 93ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 94ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 95ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static data_type Remove(data_type B, key_type K, context_type F) { 96ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return F.remove(B, K); 97ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 98ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 99ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static bool Contains(data_type B, key_type K) { 100ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return B.contains(K); 101ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 102ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 103ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline context_type MakeContext(void *p) { 104ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return *((typename data_type::Factory*) p); 105ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 106ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 107ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 108ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return new typename data_type::Factory(Alloc); 109ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 110ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 111ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static void DeleteContext(void *Ctx) { 112ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek delete (typename data_type::Factory*) Ctx; 113ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 114ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek }; 115ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 116ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek // Partial-specialization for ImmutableList. 117ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 118ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <typename T> 119ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek struct ProgramStatePartialTrait< llvm::ImmutableList<T> > { 120ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef llvm::ImmutableList<T> data_type; 121ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef T key_type; 122ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef typename data_type::Factory& context_type; 123ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 124ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static data_type Add(data_type L, key_type K, context_type F) { 125ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return F.add(K, L); 126ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 127ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 128ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static bool Contains(data_type L, key_type K) { 129ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return L.contains(K); 130ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 131ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 132ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline data_type MakeData(void *const* p) { 133ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return p ? data_type((const llvm::ImmutableListImpl<T>*) *p) 134ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek : data_type(0); 135ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 136ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 137ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline void *MakeVoidPtr(data_type D) { 138ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return (void*) D.getInternalPointer(); 139ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 140ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 141ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline context_type MakeContext(void *p) { 142ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return *((typename data_type::Factory*) p); 143ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 144ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 145ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 146ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return new typename data_type::Factory(Alloc); 147ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 148ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 149ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static void DeleteContext(void *Ctx) { 150ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek delete (typename data_type::Factory*) Ctx; 151ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 152ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek }; 153ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 154ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek // Partial specialization for bool. 155ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <> struct ProgramStatePartialTrait<bool> { 156ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef bool data_type; 157ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 158ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline data_type MakeData(void *const* p) { 159ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return p ? (data_type) (uintptr_t) *p 160ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek : data_type(); 161ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 162ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline void *MakeVoidPtr(data_type d) { 163ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return (void*) (uintptr_t) d; 164ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 165ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek }; 166ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 167ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek // Partial specialization for unsigned. 168ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek template <> struct ProgramStatePartialTrait<unsigned> { 169ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek typedef unsigned data_type; 170ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 171ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline data_type MakeData(void *const* p) { 172ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return p ? (data_type) (uintptr_t) *p 173ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek : data_type(); 174ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 175ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek static inline void *MakeVoidPtr(data_type d) { 176ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek return (void*) (uintptr_t) d; 177ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek } 178ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek }; 1795903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1805903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Partial specialization for void*. 1815903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks template <> struct ProgramStatePartialTrait<void*> { 1825903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks typedef void *data_type; 1835903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1845903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks static inline data_type MakeData(void *const* p) { 1855903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return p ? *p 1865903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks : data_type(); 1875903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } 1885903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks static inline void *MakeVoidPtr(data_type d) { 1895903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return d; 1905903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } 1915903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks }; 1925903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 193ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end GR namespace 194ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 195ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end clang namespace 196ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek 197ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#endif 198