~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/include/llvm/ADT/Twine.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
//===-- Twine.h - Fast Temporary String Concatenation -----------*- 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
#ifndef LLVM_ADT_TWINE_H
 
11
#define LLVM_ADT_TWINE_H
 
12
 
 
13
#include "llvm/ADT/StringRef.h"
 
14
#include "llvm/System/DataTypes.h"
 
15
#include <cassert>
 
16
#include <string>
 
17
 
 
18
namespace llvm {
 
19
  template <typename T>
 
20
  class SmallVectorImpl;
 
21
  class StringRef;
 
22
  class raw_ostream;
 
23
 
 
24
  /// Twine - A lightweight data structure for efficiently representing the
 
25
  /// concatenation of temporary values as strings.
 
26
  ///
 
27
  /// A Twine is a kind of rope, it represents a concatenated string using a
 
28
  /// binary-tree, where the string is the preorder of the nodes. Since the
 
29
  /// Twine can be efficiently rendered into a buffer when its result is used,
 
30
  /// it avoids the cost of generating temporary values for intermediate string
 
31
  /// results -- particularly in cases when the Twine result is never
 
32
  /// required. By explicitly tracking the type of leaf nodes, we can also avoid
 
33
  /// the creation of temporary strings for conversions operations (such as
 
34
  /// appending an integer to a string).
 
35
  ///
 
36
  /// A Twine is not intended for use directly and should not be stored, its
 
37
  /// implementation relies on the ability to store pointers to temporary stack
 
38
  /// objects which may be deallocated at the end of a statement. Twines should
 
39
  /// only be used accepted as const references in arguments, when an API wishes
 
40
  /// to accept possibly-concatenated strings.
 
41
  ///
 
42
  /// Twines support a special 'null' value, which always concatenates to form
 
43
  /// itself, and renders as an empty string. This can be returned from APIs to
 
44
  /// effectively nullify any concatenations performed on the result.
 
45
  /// 
 
46
  /// \b Implementation \n
 
47
  ///
 
48
  /// Given the nature of a Twine, it is not possible for the Twine's
 
49
  /// concatenation method to construct interior nodes; the result must be
 
50
  /// represented inside the returned value. For this reason a Twine object
 
51
  /// actually holds two values, the left- and right-hand sides of a
 
52
  /// concatenation. We also have nullary Twine objects, which are effectively
 
53
  /// sentinel values that represent empty strings.
 
54
  ///
 
55
  /// Thus, a Twine can effectively have zero, one, or two children. The \see
 
56
  /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
 
57
  /// testing the number of children.
 
58
  ///
 
59
  /// We maintain a number of invariants on Twine objects (FIXME: Why):
 
60
  ///  - Nullary twines are always represented with their Kind on the left-hand
 
61
  ///    side, and the Empty kind on the right-hand side.
 
62
  ///  - Unary twines are always represented with the value on the left-hand
 
63
  ///    side, and the Empty kind on the right-hand side.
 
64
  ///  - If a Twine has another Twine as a child, that child should always be
 
65
  ///    binary (otherwise it could have been folded into the parent).
 
66
  ///
 
67
  /// These invariants are check by \see isValid().
 
68
  ///
 
69
  /// \b Efficiency Considerations \n
 
70
  ///
 
71
  /// The Twine is designed to yield efficient and small code for common
 
72
  /// situations. For this reason, the concat() method is inlined so that
 
73
  /// concatenations of leaf nodes can be optimized into stores directly into a
 
74
  /// single stack allocated object.
 
75
  ///
 
76
  /// In practice, not all compilers can be trusted to optimize concat() fully,
 
77
  /// so we provide two additional methods (and accompanying operator+
 
78
  /// overloads) to guarantee that particularly important cases (cstring plus
 
79
  /// StringRef) codegen as desired.
 
80
  class Twine {
 
81
    /// NodeKind - Represent the type of an argument.
 
82
    enum NodeKind {
 
83
      /// An empty string; the result of concatenating anything with it is also
 
84
      /// empty.
 
85
      NullKind,
 
86
 
 
87
      /// The empty string.
 
88
      EmptyKind,
 
89
 
 
90
      /// A pointer to a Twine instance.
 
91
      TwineKind,
 
92
 
 
93
      /// A pointer to a C string instance.
 
94
      CStringKind,
 
95
 
 
96
      /// A pointer to an std::string instance.
 
97
      StdStringKind,
 
98
 
 
99
      /// A pointer to a StringRef instance.
 
100
      StringRefKind,
 
101
 
 
102
      /// A pointer to an unsigned int value, to render as an unsigned decimal
 
103
      /// integer.
 
104
      DecUIKind,
 
105
 
 
106
      /// A pointer to an int value, to render as a signed decimal integer.
 
107
      DecIKind,
 
108
 
 
109
      /// A pointer to an unsigned long value, to render as an unsigned decimal
 
110
      /// integer.
 
111
      DecULKind,
 
112
 
 
113
      /// A pointer to a long value, to render as a signed decimal integer.
 
114
      DecLKind,
 
115
 
 
116
      /// A pointer to an unsigned long long value, to render as an unsigned
 
117
      /// decimal integer.
 
118
      DecULLKind,
 
119
 
 
120
      /// A pointer to a long long value, to render as a signed decimal integer.
 
121
      DecLLKind,
 
122
 
 
123
      /// A pointer to a uint64_t value, to render as an unsigned hexadecimal
 
124
      /// integer.
 
125
      UHexKind
 
126
    };
 
127
 
 
128
  private:
 
129
    /// LHS - The prefix in the concatenation, which may be uninitialized for
 
130
    /// Null or Empty kinds.
 
131
    const void *LHS;
 
132
    /// RHS - The suffix in the concatenation, which may be uninitialized for
 
133
    /// Null or Empty kinds.
 
134
    const void *RHS;
 
135
    /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
 
136
    unsigned char LHSKind;
 
137
    /// RHSKind - The NodeKind of the left hand side, \see getLHSKind().
 
138
    unsigned char RHSKind;
 
139
 
 
140
  private:
 
141
    /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
 
142
    explicit Twine(NodeKind Kind)
 
143
      : LHSKind(Kind), RHSKind(EmptyKind) {
 
144
      assert(isNullary() && "Invalid kind!");
 
145
    }
 
146
 
 
147
    /// Construct a binary twine.
 
148
    explicit Twine(const Twine &_LHS, const Twine &_RHS)
 
149
      : LHS(&_LHS), RHS(&_RHS), LHSKind(TwineKind), RHSKind(TwineKind) {
 
150
      assert(isValid() && "Invalid twine!");
 
151
    }
 
152
 
 
153
    /// Construct a twine from explicit values.
 
154
    explicit Twine(const void *_LHS, NodeKind _LHSKind,
 
155
                   const void *_RHS, NodeKind _RHSKind)
 
156
      : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
 
157
      assert(isValid() && "Invalid twine!");
 
158
    }
 
159
 
 
160
    /// isNull - Check for the null twine.
 
161
    bool isNull() const {
 
162
      return getLHSKind() == NullKind;
 
163
    }
 
164
 
 
165
    /// isEmpty - Check for the empty twine.
 
166
    bool isEmpty() const {
 
167
      return getLHSKind() == EmptyKind;
 
168
    }
 
169
 
 
170
    /// isNullary - Check if this is a nullary twine (null or empty).
 
171
    bool isNullary() const {
 
172
      return isNull() || isEmpty();
 
173
    }
 
174
 
 
175
    /// isUnary - Check if this is a unary twine.
 
176
    bool isUnary() const {
 
177
      return getRHSKind() == EmptyKind && !isNullary();
 
178
    }
 
179
 
 
180
    /// isBinary - Check if this is a binary twine.
 
181
    bool isBinary() const {
 
182
      return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
 
183
    }
 
184
 
 
185
    /// isValid - Check if this is a valid twine (satisfying the invariants on
 
186
    /// order and number of arguments).
 
187
    bool isValid() const {
 
188
      // Nullary twines always have Empty on the RHS.
 
189
      if (isNullary() && getRHSKind() != EmptyKind)
 
190
        return false;
 
191
 
 
192
      // Null should never appear on the RHS.
 
193
      if (getRHSKind() == NullKind)
 
194
        return false;
 
195
 
 
196
      // The RHS cannot be non-empty if the LHS is empty.
 
197
      if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
 
198
        return false;
 
199
 
 
200
      // A twine child should always be binary.
 
201
      if (getLHSKind() == TwineKind &&
 
202
          !static_cast<const Twine*>(LHS)->isBinary())
 
203
        return false;
 
204
      if (getRHSKind() == TwineKind &&
 
205
          !static_cast<const Twine*>(RHS)->isBinary())
 
206
        return false;
 
207
 
 
208
      return true;
 
209
    }
 
210
 
 
211
    /// getLHSKind - Get the NodeKind of the left-hand side.
 
212
    NodeKind getLHSKind() const { return (NodeKind) LHSKind; }
 
213
 
 
214
    /// getRHSKind - Get the NodeKind of the left-hand side.
 
215
    NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
 
216
 
 
217
    /// printOneChild - Print one child from a twine.
 
218
    void printOneChild(raw_ostream &OS, const void *Ptr, NodeKind Kind) const;
 
219
 
 
220
    /// printOneChildRepr - Print the representation of one child from a twine.
 
221
    void printOneChildRepr(raw_ostream &OS, const void *Ptr,
 
222
                           NodeKind Kind) const;
 
223
 
 
224
  public:
 
225
    /// @name Constructors
 
226
    /// @{
 
227
 
 
228
    /// Construct from an empty string.
 
229
    /*implicit*/ Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) {
 
230
      assert(isValid() && "Invalid twine!");
 
231
    }
 
232
 
 
233
    /// Construct from a C string.
 
234
    ///
 
235
    /// We take care here to optimize "" into the empty twine -- this will be
 
236
    /// optimized out for string constants. This allows Twine arguments have
 
237
    /// default "" values, without introducing unnecessary string constants.
 
238
    /*implicit*/ Twine(const char *Str)
 
239
      : RHSKind(EmptyKind) {
 
240
      if (Str[0] != '\0') {
 
241
        LHS = Str;
 
242
        LHSKind = CStringKind;
 
243
      } else
 
244
        LHSKind = EmptyKind;
 
245
 
 
246
      assert(isValid() && "Invalid twine!");
 
247
    }
 
248
 
 
249
    /// Construct from an std::string.
 
250
    /*implicit*/ Twine(const std::string &Str)
 
251
      : LHS(&Str), LHSKind(StdStringKind), RHSKind(EmptyKind) {
 
252
      assert(isValid() && "Invalid twine!");
 
253
    }
 
254
 
 
255
    /// Construct from a StringRef.
 
256
    /*implicit*/ Twine(const StringRef &Str)
 
257
      : LHS(&Str), LHSKind(StringRefKind), RHSKind(EmptyKind) {
 
258
      assert(isValid() && "Invalid twine!");
 
259
    }
 
260
 
 
261
    /// Construct a twine to print \arg Val as an unsigned decimal integer.
 
262
    explicit Twine(const unsigned int &Val) 
 
263
      : LHS(&Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
 
264
    }
 
265
 
 
266
    /// Construct a twine to print \arg Val as a signed decimal integer.
 
267
    explicit Twine(const int &Val) 
 
268
      : LHS(&Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
 
269
    }
 
270
 
 
271
    /// Construct a twine to print \arg Val as an unsigned decimal integer.
 
272
    explicit Twine(const unsigned long &Val) 
 
273
      : LHS(&Val), LHSKind(DecULKind), RHSKind(EmptyKind) {
 
274
    }
 
275
 
 
276
    /// Construct a twine to print \arg Val as a signed decimal integer.
 
277
    explicit Twine(const long &Val) 
 
278
      : LHS(&Val), LHSKind(DecLKind), RHSKind(EmptyKind) {
 
279
    }
 
280
 
 
281
    /// Construct a twine to print \arg Val as an unsigned decimal integer.
 
282
    explicit Twine(const unsigned long long &Val) 
 
283
      : LHS(&Val), LHSKind(DecULLKind), RHSKind(EmptyKind) {
 
284
    }
 
285
 
 
286
    /// Construct a twine to print \arg Val as a signed decimal integer.
 
287
    explicit Twine(const long long &Val) 
 
288
      : LHS(&Val), LHSKind(DecLLKind), RHSKind(EmptyKind) {
 
289
    }
 
290
 
 
291
    // FIXME: Unfortunately, to make sure this is as efficient as possible we
 
292
    // need extra binary constructors from particular types. We can't rely on
 
293
    // the compiler to be smart enough to fold operator+()/concat() down to the
 
294
    // right thing. Yet.
 
295
 
 
296
    /// Construct as the concatenation of a C string and a StringRef.
 
297
    /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS)
 
298
      : LHS(_LHS), RHS(&_RHS), LHSKind(CStringKind), RHSKind(StringRefKind) {
 
299
      assert(isValid() && "Invalid twine!");
 
300
    }
 
301
 
 
302
    /// Construct as the concatenation of a StringRef and a C string.
 
303
    /*implicit*/ Twine(const StringRef &_LHS, const char *_RHS)
 
304
      : LHS(&_LHS), RHS(_RHS), LHSKind(StringRefKind), RHSKind(CStringKind) {
 
305
      assert(isValid() && "Invalid twine!");
 
306
    }
 
307
 
 
308
    /// Create a 'null' string, which is an empty string that always
 
309
    /// concatenates to form another empty string.
 
310
    static Twine createNull() {
 
311
      return Twine(NullKind);
 
312
    }
 
313
 
 
314
    /// @}
 
315
    /// @name Numeric Conversions
 
316
    /// @{
 
317
 
 
318
    // Construct a twine to print \arg Val as an unsigned hexadecimal integer.
 
319
    static Twine utohexstr(const uint64_t &Val) {
 
320
      return Twine(&Val, UHexKind, 0, EmptyKind);
 
321
    }
 
322
 
 
323
    /// @}
 
324
    /// @name Predicate Operations
 
325
    /// @{
 
326
 
 
327
    /// isTriviallyEmpty - Check if this twine is trivially empty; a false
 
328
    /// return value does not necessarily mean the twine is empty.
 
329
    bool isTriviallyEmpty() const {
 
330
      return isNullary();
 
331
    }
 
332
    
 
333
    /// isSingleStringRef - Return true if this twine can be dynamically
 
334
    /// accessed as a single StringRef value with getSingleStringRef().
 
335
    bool isSingleStringRef() const {
 
336
      if (getRHSKind() != EmptyKind) return false;
 
337
      
 
338
      switch (getLHSKind()) {
 
339
      case EmptyKind:
 
340
      case CStringKind:
 
341
      case StdStringKind:
 
342
      case StringRefKind:
 
343
        return true;
 
344
      default:
 
345
        return false;
 
346
      }
 
347
    }
 
348
 
 
349
    /// @}
 
350
    /// @name String Operations
 
351
    /// @{
 
352
 
 
353
    Twine concat(const Twine &Suffix) const;
 
354
 
 
355
    /// @}
 
356
    /// @name Output & Conversion.
 
357
    /// @{
 
358
 
 
359
    /// str - Return the twine contents as a std::string.
 
360
    std::string str() const;
 
361
 
 
362
    /// toVector - Write the concatenated string into the given SmallString or
 
363
    /// SmallVector.
 
364
    void toVector(SmallVectorImpl<char> &Out) const;
 
365
 
 
366
    /// getSingleStringRef - This returns the twine as a single StringRef.  This
 
367
    /// method is only valid if isSingleStringRef() is true.
 
368
    StringRef getSingleStringRef() const {
 
369
      assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
 
370
      switch (getLHSKind()) {
 
371
      default: assert(0 && "Out of sync with isSingleStringRef");
 
372
      case EmptyKind:      return StringRef();
 
373
      case CStringKind:    return StringRef((const char*)LHS);
 
374
      case StdStringKind:  return StringRef(*(const std::string*)LHS);
 
375
      case StringRefKind:  return *(const StringRef*)LHS;
 
376
      }
 
377
    }
 
378
 
 
379
    /// toStringRef - This returns the twine as a single StringRef if it can be
 
380
    /// represented as such. Otherwise the twine is written into the given
 
381
    /// SmallVector and a StringRef to the SmallVector's data is returned.
 
382
    StringRef toStringRef(SmallVectorImpl<char> &Out) const;
 
383
 
 
384
    /// print - Write the concatenated string represented by this twine to the
 
385
    /// stream \arg OS.
 
386
    void print(raw_ostream &OS) const;
 
387
 
 
388
    /// dump - Dump the concatenated string represented by this twine to stderr.
 
389
    void dump() const;
 
390
 
 
391
    /// print - Write the representation of this twine to the stream \arg OS.
 
392
    void printRepr(raw_ostream &OS) const;
 
393
 
 
394
    /// dumpRepr - Dump the representation of this twine to stderr.
 
395
    void dumpRepr() const;
 
396
 
 
397
    /// @}
 
398
  };
 
399
 
 
400
  /// @name Twine Inline Implementations
 
401
  /// @{
 
402
 
 
403
  inline Twine Twine::concat(const Twine &Suffix) const {
 
404
    // Concatenation with null is null.
 
405
    if (isNull() || Suffix.isNull())
 
406
      return Twine(NullKind);
 
407
 
 
408
    // Concatenation with empty yields the other side.
 
409
    if (isEmpty())
 
410
      return Suffix;
 
411
    if (Suffix.isEmpty())
 
412
      return *this;
 
413
 
 
414
    // Otherwise we need to create a new node, taking care to fold in unary
 
415
    // twines.
 
416
    const void *NewLHS = this, *NewRHS = &Suffix;
 
417
    NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
 
418
    if (isUnary()) {
 
419
      NewLHS = LHS;
 
420
      NewLHSKind = getLHSKind();
 
421
    }
 
422
    if (Suffix.isUnary()) {
 
423
      NewRHS = Suffix.LHS;
 
424
      NewRHSKind = Suffix.getLHSKind();
 
425
    }
 
426
 
 
427
    return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
 
428
  }
 
429
 
 
430
  inline Twine operator+(const Twine &LHS, const Twine &RHS) {
 
431
    return LHS.concat(RHS);
 
432
  }
 
433
 
 
434
  /// Additional overload to guarantee simplified codegen; this is equivalent to
 
435
  /// concat().
 
436
 
 
437
  inline Twine operator+(const char *LHS, const StringRef &RHS) {
 
438
    return Twine(LHS, RHS);
 
439
  }
 
440
 
 
441
  /// Additional overload to guarantee simplified codegen; this is equivalent to
 
442
  /// concat().
 
443
 
 
444
  inline Twine operator+(const StringRef &LHS, const char *RHS) {
 
445
    return Twine(LHS, RHS);
 
446
  }
 
447
 
 
448
  inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
 
449
    RHS.print(OS);
 
450
    return OS;
 
451
  }
 
452
 
 
453
  /// @}
 
454
}
 
455
 
 
456
#endif