aboutsummaryrefslogtreecommitdiff
path: root/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
blob: b80d494b88cb85b5f8090375f04c2b98b43bb8ac (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*-
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines partial implementations of template specializations of
//  the class ProgramStateTrait<>.  ProgramStateTrait<> is used by ProgramState 
//  to implement set/get methods for mapulating a ProgramState's
// generic data map.
//
//===----------------------------------------------------------------------===//


#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H

namespace llvm {
  class BumpPtrAllocator;
  template <typename K, typename D, typename I> class ImmutableMap;
  template <typename K, typename I> class ImmutableSet;
  template <typename T> class ImmutableList;
  template <typename T> class ImmutableListImpl;
}

namespace clang {

namespace ento {
  template <typename T> struct ProgramStatePartialTrait;

  // Partial-specialization for ImmutableMap.

  template <typename Key, typename Data, typename Info>
  struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
    typedef llvm::ImmutableMap<Key,Data,Info> data_type;
    typedef typename data_type::Factory&      context_type;
    typedef Key                               key_type;
    typedef Data                              value_type;
    typedef const value_type*                 lookup_type;

    static inline data_type MakeData(void *const* p) {
      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
    }
    static inline void *MakeVoidPtr(data_type B) {
      return B.getRoot();
    }
    static lookup_type Lookup(data_type B, key_type K) {
      return B.lookup(K);
    }
    static data_type Set(data_type B, key_type K, value_type E,context_type F){
      return F.add(B, K, E);
    }

    static data_type Remove(data_type B, key_type K, context_type F) {
      return F.remove(B, K);
    }

    static inline context_type MakeContext(void *p) {
      return *((typename data_type::Factory*) p);
    }

    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
      return new typename data_type::Factory(Alloc);
    }

    static void DeleteContext(void *Ctx) {
      delete (typename data_type::Factory*) Ctx;
    }
  };


  // Partial-specialization for ImmutableSet.

  template <typename Key, typename Info>
  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
    typedef llvm::ImmutableSet<Key,Info>      data_type;
    typedef typename data_type::Factory&      context_type;
    typedef Key                               key_type;

    static inline data_type MakeData(void *const* p) {
      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
    }

    static inline void *MakeVoidPtr(data_type B) {
      return B.getRoot();
    }

    static data_type Add(data_type B, key_type K, context_type F) {
      return F.add(B, K);
    }

    static data_type Remove(data_type B, key_type K, context_type F) {
      return F.remove(B, K);
    }

    static bool Contains(data_type B, key_type K) {
      return B.contains(K);
    }

    static inline context_type MakeContext(void *p) {
      return *((typename data_type::Factory*) p);
    }

    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
      return new typename data_type::Factory(Alloc);
    }

    static void DeleteContext(void *Ctx) {
      delete (typename data_type::Factory*) Ctx;
    }
  };

  // Partial-specialization for ImmutableList.

  template <typename T>
  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
    typedef llvm::ImmutableList<T>            data_type;
    typedef T                                 key_type;
    typedef typename data_type::Factory&      context_type;

    static data_type Add(data_type L, key_type K, context_type F) {
      return F.add(K, L);
    }

    static bool Contains(data_type L, key_type K) {
      return L.contains(K);
    }

    static inline data_type MakeData(void *const* p) {
      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
               : data_type(0);
    }

    static inline void *MakeVoidPtr(data_type D) {
      return  (void*) D.getInternalPointer();
    }

    static inline context_type MakeContext(void *p) {
      return *((typename data_type::Factory*) p);
    }

    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
      return new typename data_type::Factory(Alloc);
    }

    static void DeleteContext(void *Ctx) {
      delete (typename data_type::Factory*) Ctx;
    }
  };
  
  // Partial specialization for bool.
  template <> struct ProgramStatePartialTrait<bool> {
    typedef bool data_type;

    static inline data_type MakeData(void *const* p) {
      return p ? (data_type) (uintptr_t) *p
               : data_type();
    }
    static inline void *MakeVoidPtr(data_type d) {
      return (void*) (uintptr_t) d;
    }
  };
  
  // Partial specialization for unsigned.
  template <> struct ProgramStatePartialTrait<unsigned> {
    typedef unsigned data_type;

    static inline data_type MakeData(void *const* p) {
      return p ? (data_type) (uintptr_t) *p
               : data_type();
    }
    static inline void *MakeVoidPtr(data_type d) {
      return (void*) (uintptr_t) d;
    }
  };
  
} // end GR namespace

} // end clang namespace

#endif