clang API Documentation
00001 //ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*- 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines partial implementations of template specializations of 00011 // the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState 00012 // to implement set/get methods for manipulating a ProgramState's 00013 // generic data map. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 00018 #ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H 00019 #define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H 00020 00021 namespace llvm { 00022 class BumpPtrAllocator; 00023 template <typename K, typename D, typename I> class ImmutableMap; 00024 template <typename K, typename I> class ImmutableSet; 00025 template <typename T> class ImmutableList; 00026 template <typename T> class ImmutableListImpl; 00027 } 00028 00029 namespace clang { 00030 00031 namespace ento { 00032 template <typename T> struct ProgramStatePartialTrait; 00033 00034 // Partial-specialization for ImmutableMap. 00035 00036 template <typename Key, typename Data, typename Info> 00037 struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > { 00038 typedef llvm::ImmutableMap<Key,Data,Info> data_type; 00039 typedef typename data_type::Factory& context_type; 00040 typedef Key key_type; 00041 typedef Data value_type; 00042 typedef const value_type* lookup_type; 00043 00044 static inline data_type MakeData(void *const* p) { 00045 return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); 00046 } 00047 static inline void *MakeVoidPtr(data_type B) { 00048 return B.getRoot(); 00049 } 00050 static lookup_type Lookup(data_type B, key_type K) { 00051 return B.lookup(K); 00052 } 00053 static data_type Set(data_type B, key_type K, value_type E,context_type F){ 00054 return F.add(B, K, E); 00055 } 00056 00057 static data_type Remove(data_type B, key_type K, context_type F) { 00058 return F.remove(B, K); 00059 } 00060 00061 static inline context_type MakeContext(void *p) { 00062 return *((typename data_type::Factory*) p); 00063 } 00064 00065 static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 00066 return new typename data_type::Factory(Alloc); 00067 } 00068 00069 static void DeleteContext(void *Ctx) { 00070 delete (typename data_type::Factory*) Ctx; 00071 } 00072 }; 00073 00074 00075 // Partial-specialization for ImmutableSet. 00076 00077 template <typename Key, typename Info> 00078 struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > { 00079 typedef llvm::ImmutableSet<Key,Info> data_type; 00080 typedef typename data_type::Factory& context_type; 00081 typedef Key key_type; 00082 00083 static inline data_type MakeData(void *const* p) { 00084 return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); 00085 } 00086 00087 static inline void *MakeVoidPtr(data_type B) { 00088 return B.getRoot(); 00089 } 00090 00091 static data_type Add(data_type B, key_type K, context_type F) { 00092 return F.add(B, K); 00093 } 00094 00095 static data_type Remove(data_type B, key_type K, context_type F) { 00096 return F.remove(B, K); 00097 } 00098 00099 static bool Contains(data_type B, key_type K) { 00100 return B.contains(K); 00101 } 00102 00103 static inline context_type MakeContext(void *p) { 00104 return *((typename data_type::Factory*) p); 00105 } 00106 00107 static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 00108 return new typename data_type::Factory(Alloc); 00109 } 00110 00111 static void DeleteContext(void *Ctx) { 00112 delete (typename data_type::Factory*) Ctx; 00113 } 00114 }; 00115 00116 // Partial-specialization for ImmutableList. 00117 00118 template <typename T> 00119 struct ProgramStatePartialTrait< llvm::ImmutableList<T> > { 00120 typedef llvm::ImmutableList<T> data_type; 00121 typedef T key_type; 00122 typedef typename data_type::Factory& context_type; 00123 00124 static data_type Add(data_type L, key_type K, context_type F) { 00125 return F.add(K, L); 00126 } 00127 00128 static bool Contains(data_type L, key_type K) { 00129 return L.contains(K); 00130 } 00131 00132 static inline data_type MakeData(void *const* p) { 00133 return p ? data_type((const llvm::ImmutableListImpl<T>*) *p) 00134 : data_type(0); 00135 } 00136 00137 static inline void *MakeVoidPtr(data_type D) { 00138 return (void*) D.getInternalPointer(); 00139 } 00140 00141 static inline context_type MakeContext(void *p) { 00142 return *((typename data_type::Factory*) p); 00143 } 00144 00145 static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { 00146 return new typename data_type::Factory(Alloc); 00147 } 00148 00149 static void DeleteContext(void *Ctx) { 00150 delete (typename data_type::Factory*) Ctx; 00151 } 00152 }; 00153 00154 // Partial specialization for bool. 00155 template <> struct ProgramStatePartialTrait<bool> { 00156 typedef bool data_type; 00157 00158 static inline data_type MakeData(void *const* p) { 00159 return p ? (data_type) (uintptr_t) *p 00160 : data_type(); 00161 } 00162 static inline void *MakeVoidPtr(data_type d) { 00163 return (void*) (uintptr_t) d; 00164 } 00165 }; 00166 00167 // Partial specialization for unsigned. 00168 template <> struct ProgramStatePartialTrait<unsigned> { 00169 typedef unsigned data_type; 00170 00171 static inline data_type MakeData(void *const* p) { 00172 return p ? (data_type) (uintptr_t) *p 00173 : data_type(); 00174 } 00175 static inline void *MakeVoidPtr(data_type d) { 00176 return (void*) (uintptr_t) d; 00177 } 00178 }; 00179 00180 // Partial specialization for void*. 00181 template <> struct ProgramStatePartialTrait<void*> { 00182 typedef void *data_type; 00183 00184 static inline data_type MakeData(void *const* p) { 00185 return p ? *p 00186 : data_type(); 00187 } 00188 static inline void *MakeVoidPtr(data_type d) { 00189 return d; 00190 } 00191 }; 00192 00193 } // end GR namespace 00194 00195 } // end clang namespace 00196 00197 #endif