Coverage Report

Created: 2018-08-19 21:11

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Demangle/Utility.h
Line
Count
Source (jump to first uncovered line)
1
//===--- Utility.h ----------------------------------------------*- 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
// This file contains several utility classes used by the demangle library.
10
//===----------------------------------------------------------------------===//
11
12
#ifndef LLVM_DEMANGLE_UTILITY_H
13
#define LLVM_DEMANGLE_UTILITY_H
14
15
#include "StringView.h"
16
17
#include <cstdint>
18
#include <cstdlib>
19
#include <cstring>
20
#include <iterator>
21
#include <limits>
22
23
// Stream that AST nodes write their string representation into after the AST
24
// has been parsed.
25
class OutputStream {
26
  char *Buffer;
27
  size_t CurrentPosition;
28
  size_t BufferCapacity;
29
30
  // Ensure there is at least n more positions in buffer.
31
17.0k
  void grow(size_t N) {
32
17.0k
    if (N + CurrentPosition >= BufferCapacity) {
33
93
      BufferCapacity *= 2;
34
93
      if (BufferCapacity < N + CurrentPosition)
35
6
        BufferCapacity = N + CurrentPosition;
36
93
      Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
37
93
      if (Buffer == nullptr)
38
0
        std::terminate();
39
93
    }
40
17.0k
  }
41
42
  void writeUnsigned(uint64_t N, bool isNeg = false) {
43
    // Handle special case...
44
    if (N == 0) {
45
      *this << '0';
46
      return;
47
    }
48
49
    char Temp[21];
50
    char *TempPtr = std::end(Temp);
51
52
    while (N) {
53
      *--TempPtr = '0' + char(N % 10);
54
      N /= 10;
55
    }
56
57
    // Add negative sign...
58
    if (isNeg)
59
      *--TempPtr = '-';
60
    this->operator<<(StringView(TempPtr, std::end(Temp)));
61
  }
62
63
public:
64
  OutputStream(char *StartBuf, size_t Size)
65
0
      : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
66
2.23k
  OutputStream() = default;
67
1.85k
  void reset(char *Buffer_, size_t BufferCapacity_) {
68
1.85k
    CurrentPosition = 0;
69
1.85k
    Buffer = Buffer_;
70
1.85k
    BufferCapacity = BufferCapacity_;
71
1.85k
  }
72
73
  /// Create an OutputStream from a buffer and a size.  If either of these are
74
  /// null a buffer is allocated.
75
  static OutputStream create(char *StartBuf, size_t *Size, size_t AllocSize) {
76
    OutputStream Result;
77
78
    if (!StartBuf || !Size) {
79
      StartBuf = static_cast<char *>(std::malloc(AllocSize));
80
      if (StartBuf == nullptr)
81
        std::terminate();
82
      Size = &AllocSize;
83
    }
84
85
    Result.reset(StartBuf, *Size);
86
    return Result;
87
  }
88
89
  /// If a ParameterPackExpansion (or similar type) is encountered, the offset
90
  /// into the pack that we're currently printing.
91
  unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
92
  unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
93
94
14.5k
  OutputStream &operator+=(StringView R) {
95
14.5k
    size_t Size = R.size();
96
14.5k
    if (Size == 0)
97
3
      return *this;
98
14.5k
    grow(Size);
99
14.5k
    std::memmove(Buffer + CurrentPosition, R.begin(), Size);
100
14.5k
    CurrentPosition += Size;
101
14.5k
    return *this;
102
14.5k
  }
103
104
2.44k
  OutputStream &operator+=(char C) {
105
2.44k
    grow(1);
106
2.44k
    Buffer[CurrentPosition++] = C;
107
2.44k
    return *this;
108
2.44k
  }
109
110
  OutputStream &operator<<(StringView R) { return (*this += R); }
111
112
  OutputStream &operator<<(char C) { return (*this += C); }
113
114
  OutputStream &operator<<(long long N) {
115
    if (N < 0)
116
      writeUnsigned(static_cast<unsigned long long>(-N), true);
117
    else
118
      writeUnsigned(static_cast<unsigned long long>(N));
119
    return *this;
120
  }
121
122
  OutputStream &operator<<(unsigned long long N) {
123
    writeUnsigned(N, false);
124
    return *this;
125
  }
126
127
0
  OutputStream &operator<<(long N) {
128
0
    return this->operator<<(static_cast<long long>(N));
129
0
  }
130
131
0
  OutputStream &operator<<(unsigned long N) {
132
0
    return this->operator<<(static_cast<unsigned long long>(N));
133
0
  }
134
135
  OutputStream &operator<<(int N) {
136
    return this->operator<<(static_cast<long long>(N));
137
  }
138
139
  OutputStream &operator<<(unsigned int N) {
140
    return this->operator<<(static_cast<unsigned long long>(N));
141
  }
142
143
418
  size_t getCurrentPosition() const { return CurrentPosition; }
144
0
  void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
145
146
2.79k
  char back() const {
147
2.79k
    return CurrentPosition ? Buffer[CurrentPosition - 1] : 
'\0'0
;
148
2.79k
  }
149
150
  bool empty() const { return CurrentPosition == 0; }
151
152
1.85k
  char *getBuffer() { return Buffer; }
153
0
  char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
154
0
  size_t getBufferCapacity() { return BufferCapacity; }
155
};
156
157
template <class T> class SwapAndRestore {
158
  T &Restore;
159
  T OriginalValue;
160
  bool ShouldRestore = true;
161
162
public:
163
  SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
164
165
  SwapAndRestore(T &Restore_, T NewVal)
166
22
      : Restore(Restore_), OriginalValue(Restore) {
167
22
    Restore = std::move(NewVal);
168
22
  }
SwapAndRestore<bool>::SwapAndRestore(bool&, bool)
Line
Count
Source
166
18
      : Restore(Restore_), OriginalValue(Restore) {
167
18
    Restore = std::move(NewVal);
168
18
  }
SwapAndRestore<unsigned int>::SwapAndRestore(unsigned int&, unsigned int)
Line
Count
Source
166
4
      : Restore(Restore_), OriginalValue(Restore) {
167
4
    Restore = std::move(NewVal);
168
4
  }
Unexecuted instantiation: SwapAndRestore<char const*>::SwapAndRestore(char const*&, char const*)
169
22
  ~SwapAndRestore() {
170
22
    if (ShouldRestore)
171
22
      Restore = std::move(OriginalValue);
172
22
  }
SwapAndRestore<bool>::~SwapAndRestore()
Line
Count
Source
169
18
  ~SwapAndRestore() {
170
18
    if (ShouldRestore)
171
18
      Restore = std::move(OriginalValue);
172
18
  }
SwapAndRestore<unsigned int>::~SwapAndRestore()
Line
Count
Source
169
4
  ~SwapAndRestore() {
170
4
    if (ShouldRestore)
171
4
      Restore = std::move(OriginalValue);
172
4
  }
Unexecuted instantiation: SwapAndRestore<char const*>::~SwapAndRestore()
173
174
  void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
175
176
  void restoreNow(bool Force) {
177
    if (!Force && !ShouldRestore)
178
      return;
179
180
    Restore = std::move(OriginalValue);
181
    ShouldRestore = false;
182
  }
183
184
  SwapAndRestore(const SwapAndRestore &) = delete;
185
  SwapAndRestore &operator=(const SwapAndRestore &) = delete;
186
};
187
188
#endif