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