~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/include/llvm/ADT/ValueMap.h

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- llvm/ADT/ValueMap.h - Safe map from Values to data -------*- 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 the ValueMap class.  ValueMap maps Value* or any subclass
 
11
// to an arbitrary other type.  It provides the DenseMap interface but updates
 
12
// itself to remain safe when keys are RAUWed or deleted.  By default, when a
 
13
// key is RAUWed from V1 to V2, the old mapping V1->target is removed, and a new
 
14
// mapping V2->target is added.  If V2 already existed, its old target is
 
15
// overwritten.  When a key is deleted, its mapping is removed.
 
16
//
 
17
// You can override a ValueMap's Config parameter to control exactly what
 
18
// happens on RAUW and destruction and to get called back on each event.  It's
 
19
// legal to call back into the ValueMap from a Config's callbacks.  Config
 
20
// parameters should inherit from ValueMapConfig<KeyT> to get default
 
21
// implementations of all the methods ValueMap uses.  See ValueMapConfig for
 
22
// documentation of the functions you can override.
 
23
//
 
24
//===----------------------------------------------------------------------===//
 
25
 
 
26
#ifndef LLVM_ADT_VALUEMAP_H
 
27
#define LLVM_ADT_VALUEMAP_H
 
28
 
 
29
#include "llvm/ADT/DenseMap.h"
 
30
#include "llvm/Support/ValueHandle.h"
 
31
#include "llvm/Support/type_traits.h"
 
32
#include "llvm/System/Mutex.h"
 
33
 
 
34
#include <iterator>
 
35
 
 
36
namespace llvm {
 
37
 
 
38
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
 
39
class ValueMapCallbackVH;
 
40
 
 
41
template<typename DenseMapT, typename KeyT>
 
42
class ValueMapIterator;
 
43
template<typename DenseMapT, typename KeyT>
 
44
class ValueMapConstIterator;
 
45
 
 
46
/// This class defines the default behavior for configurable aspects of
 
47
/// ValueMap<>.  User Configs should inherit from this class to be as compatible
 
48
/// as possible with future versions of ValueMap.
 
49
template<typename KeyT>
 
50
struct ValueMapConfig {
 
51
  /// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
 
52
  /// false, the ValueMap will leave the original mapping in place.
 
53
  enum { FollowRAUW = true };
 
54
 
 
55
  // All methods will be called with a first argument of type ExtraData.  The
 
56
  // default implementations in this class take a templated first argument so
 
57
  // that users' subclasses can use any type they want without having to
 
58
  // override all the defaults.
 
59
  struct ExtraData {};
 
60
 
 
61
  template<typename ExtraDataT>
 
62
  static void onRAUW(const ExtraDataT &Data, KeyT Old, KeyT New) {}
 
63
  template<typename ExtraDataT>
 
64
  static void onDelete(const ExtraDataT &Data, KeyT Old) {}
 
65
 
 
66
  /// Returns a mutex that should be acquired around any changes to the map.
 
67
  /// This is only acquired from the CallbackVH (and held around calls to onRAUW
 
68
  /// and onDelete) and not inside other ValueMap methods.  NULL means that no
 
69
  /// mutex is necessary.
 
70
  template<typename ExtraDataT>
 
71
  static sys::Mutex *getMutex(const ExtraDataT &Data) { return NULL; }
 
72
};
 
73
 
 
74
/// See the file comment.
 
75
template<typename KeyT, typename ValueT, typename Config = ValueMapConfig<KeyT>,
 
76
         typename ValueInfoT = DenseMapInfo<ValueT> >
 
77
class ValueMap {
 
78
  friend class ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT>;
 
79
  typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> ValueMapCVH;
 
80
  typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>,
 
81
                   ValueInfoT> MapT;
 
82
  typedef typename Config::ExtraData ExtraData;
 
83
  MapT Map;
 
84
  ExtraData Data;
 
85
public:
 
86
  typedef KeyT key_type;
 
87
  typedef ValueT mapped_type;
 
88
  typedef std::pair<KeyT, ValueT> value_type;
 
89
 
 
90
  ValueMap(const ValueMap& Other) : Map(Other.Map), Data(Other.Data) {}
 
91
 
 
92
  explicit ValueMap(unsigned NumInitBuckets = 64)
 
93
    : Map(NumInitBuckets), Data() {}
 
94
  explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
 
95
    : Map(NumInitBuckets), Data(Data) {}
 
96
 
 
97
  ~ValueMap() {}
 
98
 
 
99
  typedef ValueMapIterator<MapT, KeyT> iterator;
 
100
  typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
 
101
  inline iterator begin() { return iterator(Map.begin()); }
 
102
  inline iterator end() { return iterator(Map.end()); }
 
103
  inline const_iterator begin() const { return const_iterator(Map.begin()); }
 
104
  inline const_iterator end() const { return const_iterator(Map.end()); }
 
105
 
 
106
  bool empty() const { return Map.empty(); }
 
107
  unsigned size() const { return Map.size(); }
 
108
 
 
109
  /// Grow the map so that it has at least Size buckets. Does not shrink
 
110
  void resize(size_t Size) { Map.resize(Size); }
 
111
 
 
112
  void clear() { Map.clear(); }
 
113
 
 
114
  /// count - Return true if the specified key is in the map.
 
115
  bool count(const KeyT &Val) const {
 
116
    return Map.count(Wrap(Val));
 
117
  }
 
118
 
 
119
  iterator find(const KeyT &Val) {
 
120
    return iterator(Map.find(Wrap(Val)));
 
121
  }
 
122
  const_iterator find(const KeyT &Val) const {
 
123
    return const_iterator(Map.find(Wrap(Val)));
 
124
  }
 
125
 
 
126
  /// lookup - Return the entry for the specified key, or a default
 
127
  /// constructed value if no such entry exists.
 
128
  ValueT lookup(const KeyT &Val) const {
 
129
    return Map.lookup(Wrap(Val));
 
130
  }
 
131
 
 
132
  // Inserts key,value pair into the map if the key isn't already in the map.
 
133
  // If the key is already in the map, it returns false and doesn't update the
 
134
  // value.
 
135
  std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
 
136
    std::pair<typename MapT::iterator, bool> map_result=
 
137
      Map.insert(std::make_pair(Wrap(KV.first), KV.second));
 
138
    return std::make_pair(iterator(map_result.first), map_result.second);
 
139
  }
 
140
 
 
141
  /// insert - Range insertion of pairs.
 
142
  template<typename InputIt>
 
143
  void insert(InputIt I, InputIt E) {
 
144
    for (; I != E; ++I)
 
145
      insert(*I);
 
146
  }
 
147
 
 
148
 
 
149
  bool erase(const KeyT &Val) {
 
150
    return Map.erase(Wrap(Val));
 
151
  }
 
152
  bool erase(iterator I) {
 
153
    return Map.erase(I.base());
 
154
  }
 
155
 
 
156
  value_type& FindAndConstruct(const KeyT &Key) {
 
157
    return Map.FindAndConstruct(Wrap(Key));
 
158
  }
 
159
 
 
160
  ValueT &operator[](const KeyT &Key) {
 
161
    return Map[Wrap(Key)];
 
162
  }
 
163
 
 
164
  ValueMap& operator=(const ValueMap& Other) {
 
165
    Map = Other.Map;
 
166
    Data = Other.Data;
 
167
    return *this;
 
168
  }
 
169
 
 
170
  /// isPointerIntoBucketsArray - Return true if the specified pointer points
 
171
  /// somewhere into the ValueMap's array of buckets (i.e. either to a key or
 
172
  /// value in the ValueMap).
 
173
  bool isPointerIntoBucketsArray(const void *Ptr) const {
 
174
    return Map.isPointerIntoBucketsArray(Ptr);
 
175
  }
 
176
 
 
177
  /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
 
178
  /// array.  In conjunction with the previous method, this can be used to
 
179
  /// determine whether an insertion caused the ValueMap to reallocate.
 
180
  const void *getPointerIntoBucketsArray() const {
 
181
    return Map.getPointerIntoBucketsArray();
 
182
  }
 
183
 
 
184
private:
 
185
  // Takes a key being looked up in the map and wraps it into a
 
186
  // ValueMapCallbackVH, the actual key type of the map.  We use a helper
 
187
  // function because ValueMapCVH is constructed with a second parameter.
 
188
  ValueMapCVH Wrap(KeyT key) const {
 
189
    // The only way the resulting CallbackVH could try to modify *this (making
 
190
    // the const_cast incorrect) is if it gets inserted into the map.  But then
 
191
    // this function must have been called from a non-const method, making the
 
192
    // const_cast ok.
 
193
    return ValueMapCVH(key, const_cast<ValueMap*>(this));
 
194
  }
 
195
};
 
196
 
 
197
// This CallbackVH updates its ValueMap when the contained Value changes,
 
198
// according to the user's preferences expressed through the Config object.
 
199
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
 
200
class ValueMapCallbackVH : public CallbackVH {
 
201
  friend class ValueMap<KeyT, ValueT, Config, ValueInfoT>;
 
202
  friend struct DenseMapInfo<ValueMapCallbackVH>;
 
203
  typedef ValueMap<KeyT, ValueT, Config, ValueInfoT> ValueMapT;
 
204
  typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT;
 
205
 
 
206
  ValueMapT *Map;
 
207
 
 
208
  ValueMapCallbackVH(KeyT Key, ValueMapT *Map)
 
209
      : CallbackVH(const_cast<Value*>(static_cast<const Value*>(Key))),
 
210
        Map(Map) {}
 
211
 
 
212
public:
 
213
  KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); }
 
214
 
 
215
  virtual void deleted() {
 
216
    // Make a copy that won't get changed even when *this is destroyed.
 
217
    ValueMapCallbackVH Copy(*this);
 
218
    sys::Mutex *M = Config::getMutex(Copy.Map->Data);
 
219
    if (M)
 
220
      M->acquire();
 
221
    Config::onDelete(Copy.Map->Data, Copy.Unwrap());  // May destroy *this.
 
222
    Copy.Map->Map.erase(Copy);  // Definitely destroys *this.
 
223
    if (M)
 
224
      M->release();
 
225
  }
 
226
  virtual void allUsesReplacedWith(Value *new_key) {
 
227
    assert(isa<KeySansPointerT>(new_key) &&
 
228
           "Invalid RAUW on key of ValueMap<>");
 
229
    // Make a copy that won't get changed even when *this is destroyed.
 
230
    ValueMapCallbackVH Copy(*this);
 
231
    sys::Mutex *M = Config::getMutex(Copy.Map->Data);
 
232
    if (M)
 
233
      M->acquire();
 
234
 
 
235
    KeyT typed_new_key = cast<KeySansPointerT>(new_key);
 
236
    // Can destroy *this:
 
237
    Config::onRAUW(Copy.Map->Data, Copy.Unwrap(), typed_new_key);
 
238
    if (Config::FollowRAUW) {
 
239
      typename ValueMapT::MapT::iterator I = Copy.Map->Map.find(Copy);
 
240
      // I could == Copy.Map->Map.end() if the onRAUW callback already
 
241
      // removed the old mapping.
 
242
      if (I != Copy.Map->Map.end()) {
 
243
        ValueT Target(I->second);
 
244
        Copy.Map->Map.erase(I);  // Definitely destroys *this.
 
245
        Copy.Map->insert(std::make_pair(typed_new_key, Target));
 
246
      }
 
247
    }
 
248
    if (M)
 
249
      M->release();
 
250
  }
 
251
};
 
252
 
 
253
  
 
254
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
 
255
struct isPodLike<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
 
256
  static const bool value = true;
 
257
};
 
258
 
 
259
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
 
260
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
 
261
  typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH;
 
262
  typedef DenseMapInfo<KeyT> PointerInfo;
 
263
 
 
264
  static inline VH getEmptyKey() {
 
265
    return VH(PointerInfo::getEmptyKey(), NULL);
 
266
  }
 
267
  static inline VH getTombstoneKey() {
 
268
    return VH(PointerInfo::getTombstoneKey(), NULL);
 
269
  }
 
270
  static unsigned getHashValue(const VH &Val) {
 
271
    return PointerInfo::getHashValue(Val.Unwrap());
 
272
  }
 
273
  static bool isEqual(const VH &LHS, const VH &RHS) {
 
274
    return LHS == RHS;
 
275
  }
 
276
};
 
277
 
 
278
 
 
279
template<typename DenseMapT, typename KeyT>
 
280
class ValueMapIterator :
 
281
    public std::iterator<std::forward_iterator_tag,
 
282
                         std::pair<KeyT, typename DenseMapT::mapped_type>,
 
283
                         ptrdiff_t> {
 
284
  typedef typename DenseMapT::iterator BaseT;
 
285
  typedef typename DenseMapT::mapped_type ValueT;
 
286
  BaseT I;
 
287
public:
 
288
  ValueMapIterator() : I() {}
 
289
 
 
290
  ValueMapIterator(BaseT I) : I(I) {}
 
291
 
 
292
  BaseT base() const { return I; }
 
293
 
 
294
  struct ValueTypeProxy {
 
295
    const KeyT first;
 
296
    ValueT& second;
 
297
    ValueTypeProxy *operator->() { return this; }
 
298
    operator std::pair<KeyT, ValueT>() const {
 
299
      return std::make_pair(first, second);
 
300
    }
 
301
  };
 
302
 
 
303
  ValueTypeProxy operator*() const {
 
304
    ValueTypeProxy Result = {I->first.Unwrap(), I->second};
 
305
    return Result;
 
306
  }
 
307
 
 
308
  ValueTypeProxy operator->() const {
 
309
    return operator*();
 
310
  }
 
311
 
 
312
  bool operator==(const ValueMapIterator &RHS) const {
 
313
    return I == RHS.I;
 
314
  }
 
315
  bool operator!=(const ValueMapIterator &RHS) const {
 
316
    return I != RHS.I;
 
317
  }
 
318
 
 
319
  inline ValueMapIterator& operator++() {  // Preincrement
 
320
    ++I;
 
321
    return *this;
 
322
  }
 
323
  ValueMapIterator operator++(int) {  // Postincrement
 
324
    ValueMapIterator tmp = *this; ++*this; return tmp;
 
325
  }
 
326
};
 
327
 
 
328
template<typename DenseMapT, typename KeyT>
 
329
class ValueMapConstIterator :
 
330
    public std::iterator<std::forward_iterator_tag,
 
331
                         std::pair<KeyT, typename DenseMapT::mapped_type>,
 
332
                         ptrdiff_t> {
 
333
  typedef typename DenseMapT::const_iterator BaseT;
 
334
  typedef typename DenseMapT::mapped_type ValueT;
 
335
  BaseT I;
 
336
public:
 
337
  ValueMapConstIterator() : I() {}
 
338
  ValueMapConstIterator(BaseT I) : I(I) {}
 
339
  ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other)
 
340
    : I(Other.base()) {}
 
341
 
 
342
  BaseT base() const { return I; }
 
343
 
 
344
  struct ValueTypeProxy {
 
345
    const KeyT first;
 
346
    const ValueT& second;
 
347
    ValueTypeProxy *operator->() { return this; }
 
348
    operator std::pair<KeyT, ValueT>() const {
 
349
      return std::make_pair(first, second);
 
350
    }
 
351
  };
 
352
 
 
353
  ValueTypeProxy operator*() const {
 
354
    ValueTypeProxy Result = {I->first.Unwrap(), I->second};
 
355
    return Result;
 
356
  }
 
357
 
 
358
  ValueTypeProxy operator->() const {
 
359
    return operator*();
 
360
  }
 
361
 
 
362
  bool operator==(const ValueMapConstIterator &RHS) const {
 
363
    return I == RHS.I;
 
364
  }
 
365
  bool operator!=(const ValueMapConstIterator &RHS) const {
 
366
    return I != RHS.I;
 
367
  }
 
368
 
 
369
  inline ValueMapConstIterator& operator++() {  // Preincrement
 
370
    ++I;
 
371
    return *this;
 
372
  }
 
373
  ValueMapConstIterator operator++(int) {  // Postincrement
 
374
    ValueMapConstIterator tmp = *this; ++*this; return tmp;
 
375
  }
 
376
};
 
377
 
 
378
} // end namespace llvm
 
379
 
 
380
#endif