Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
Line
Count
Source (jump to first uncovered line)
1
//===- CodeViewRecordIO.h ---------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
10
#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
11
12
#include "llvm/ADT/APSInt.h"
13
#include "llvm/ADT/None.h"
14
#include "llvm/ADT/Optional.h"
15
#include "llvm/ADT/SmallVector.h"
16
#include "llvm/ADT/StringRef.h"
17
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
18
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
19
#include "llvm/Support/BinaryStreamReader.h"
20
#include "llvm/Support/BinaryStreamWriter.h"
21
#include "llvm/Support/Error.h"
22
#include <cassert>
23
#include <cstdint>
24
#include <type_traits>
25
26
namespace llvm {
27
28
namespace codeview {
29
30
class CodeViewRecordStreamer {
31
public:
32
  virtual void EmitBytes(StringRef Data) = 0;
33
  virtual void EmitIntValue(uint64_t Value, unsigned Size) = 0;
34
  virtual void EmitBinaryData(StringRef Data) = 0;
35
  virtual void AddComment(const Twine &T) = 0;
36
190
  virtual ~CodeViewRecordStreamer() = default;
37
};
38
39
class CodeViewRecordIO {
40
133k
  uint32_t getCurrentOffset() const {
41
133k
    if (isWriting())
42
40.3k
      return Writer->getOffset();
43
93.6k
    else if (isReading())
44
78.6k
      return Reader->getOffset();
45
14.9k
    else
46
14.9k
      return 0;
47
133k
  }
48
49
public:
50
  // deserializes records to structures
51
28.5k
  explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
52
53
  // serializes records to buffer
54
6.79k
  explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
55
56
  // writes records to assembly file using MC library interface
57
  explicit CodeViewRecordIO(CodeViewRecordStreamer &Streamer)
58
190
      : Streamer(&Streamer) {}
59
60
  Error beginRecord(Optional<uint32_t> MaxLength);
61
  Error endRecord();
62
63
  Error mapInteger(TypeIndex &TypeInd, const Twine &Comment = "");
64
65
750k
  bool isStreaming() const {
66
750k
    return (Streamer != nullptr) && 
(Reader == nullptr)249k
&&
(Writer == nullptr)249k
;
67
750k
  }
68
192k
  bool isReading() const {
69
192k
    return (Reader != nullptr) && 
(Streamer == nullptr)134k
&&
(Writer == nullptr)134k
;
70
192k
  }
71
472k
  bool isWriting() const {
72
472k
    return (Writer != nullptr) && 
(Streamer == nullptr)109k
&&
(Reader == nullptr)109k
;
73
472k
  }
74
75
  uint32_t maxFieldLength() const;
76
77
232
  template <typename T> Error mapObject(T &Value) {
78
232
    if (isStreaming()) {
79
0
      StringRef BytesSR =
80
0
          StringRef((reinterpret_cast<const char *>(&Value)), sizeof(Value));
81
0
      Streamer->EmitBytes(BytesSR);
82
0
      incrStreamedLen(sizeof(T));
83
0
      return Error::success();
84
0
    }
85
232
86
232
    if (isWriting())
87
30
      return Writer->writeObject(Value);
88
202
89
202
    const T *ValuePtr;
90
202
    if (auto EC = Reader->readObject(ValuePtr))
91
0
      return EC;
92
202
    Value = *ValuePtr;
93
202
    return Error::success();
94
202
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapObject<llvm::support::detail::packed_endian_specific_integral<unsigned short, (llvm::support::endianness)1, 1ul> >(llvm::support::detail::packed_endian_specific_integral<unsigned short, (llvm::support::endianness)1, 1ul>&)
Line
Count
Source
77
192
  template <typename T> Error mapObject(T &Value) {
78
192
    if (isStreaming()) {
79
0
      StringRef BytesSR =
80
0
          StringRef((reinterpret_cast<const char *>(&Value)), sizeof(Value));
81
0
      Streamer->EmitBytes(BytesSR);
82
0
      incrStreamedLen(sizeof(T));
83
0
      return Error::success();
84
0
    }
85
192
86
192
    if (isWriting())
87
26
      return Writer->writeObject(Value);
88
166
89
166
    const T *ValuePtr;
90
166
    if (auto EC = Reader->readObject(ValuePtr))
91
0
      return EC;
92
166
    Value = *ValuePtr;
93
166
    return Error::success();
94
166
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapObject<llvm::support::detail::packed_endian_specific_integral<int, (llvm::support::endianness)1, 1ul> >(llvm::support::detail::packed_endian_specific_integral<int, (llvm::support::endianness)1, 1ul>&)
Line
Count
Source
77
33
  template <typename T> Error mapObject(T &Value) {
78
33
    if (isStreaming()) {
79
0
      StringRef BytesSR =
80
0
          StringRef((reinterpret_cast<const char *>(&Value)), sizeof(Value));
81
0
      Streamer->EmitBytes(BytesSR);
82
0
      incrStreamedLen(sizeof(T));
83
0
      return Error::success();
84
0
    }
85
33
86
33
    if (isWriting())
87
4
      return Writer->writeObject(Value);
88
29
89
29
    const T *ValuePtr;
90
29
    if (auto EC = Reader->readObject(ValuePtr))
91
0
      return EC;
92
29
    Value = *ValuePtr;
93
29
    return Error::success();
94
29
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapObject<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> >(llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul>&)
Line
Count
Source
77
7
  template <typename T> Error mapObject(T &Value) {
78
7
    if (isStreaming()) {
79
0
      StringRef BytesSR =
80
0
          StringRef((reinterpret_cast<const char *>(&Value)), sizeof(Value));
81
0
      Streamer->EmitBytes(BytesSR);
82
0
      incrStreamedLen(sizeof(T));
83
0
      return Error::success();
84
0
    }
85
7
86
7
    if (isWriting())
87
0
      return Writer->writeObject(Value);
88
7
89
7
    const T *ValuePtr;
90
7
    if (auto EC = Reader->readObject(ValuePtr))
91
0
      return EC;
92
7
    Value = *ValuePtr;
93
7
    return Error::success();
94
7
  }
95
96
132k
  template <typename T> Error mapInteger(T &Value, const Twine &Comment = "") {
97
132k
    if (isStreaming()) {
98
26.7k
      emitComment(Comment);
99
26.7k
      Streamer->EmitIntValue((int)Value, sizeof(T));
100
26.7k
      incrStreamedLen(sizeof(T));
101
26.7k
      return Error::success();
102
26.7k
    }
103
105k
104
105k
    if (isWriting())
105
24.5k
      return Writer->writeInteger(Value);
106
80.7k
107
80.7k
    return Reader->readInteger(Value);
108
80.7k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapInteger<unsigned char>(unsigned char&, llvm::Twine const&)
Line
Count
Source
96
10.2k
  template <typename T> Error mapInteger(T &Value, const Twine &Comment = "") {
97
10.2k
    if (isStreaming()) {
98
843
      emitComment(Comment);
99
843
      Streamer->EmitIntValue((int)Value, sizeof(T));
100
843
      incrStreamedLen(sizeof(T));
101
843
      return Error::success();
102
843
    }
103
9.42k
104
9.42k
    if (isWriting())
105
2.28k
      return Writer->writeInteger(Value);
106
7.14k
107
7.14k
    return Reader->readInteger(Value);
108
7.14k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapInteger<unsigned short>(unsigned short&, llvm::Twine const&)
Line
Count
Source
96
102k
  template <typename T> Error mapInteger(T &Value, const Twine &Comment = "") {
97
102k
    if (isStreaming()) {
98
25.1k
      emitComment(Comment);
99
25.1k
      Streamer->EmitIntValue((int)Value, sizeof(T));
100
25.1k
      incrStreamedLen(sizeof(T));
101
25.1k
      return Error::success();
102
25.1k
    }
103
77.1k
104
77.1k
    if (isWriting())
105
17.5k
      return Writer->writeInteger(Value);
106
59.6k
107
59.6k
    return Reader->readInteger(Value);
108
59.6k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapInteger<unsigned int>(unsigned int&, llvm::Twine const&)
Line
Count
Source
96
16.2k
  template <typename T> Error mapInteger(T &Value, const Twine &Comment = "") {
97
16.2k
    if (isStreaming()) {
98
575
      emitComment(Comment);
99
575
      Streamer->EmitIntValue((int)Value, sizeof(T));
100
575
      incrStreamedLen(sizeof(T));
101
575
      return Error::success();
102
575
    }
103
15.6k
104
15.6k
    if (isWriting())
105
4.33k
      return Writer->writeInteger(Value);
106
11.3k
107
11.3k
    return Reader->readInteger(Value);
108
11.3k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapInteger<int>(int&, llvm::Twine const&)
Line
Count
Source
96
3.21k
  template <typename T> Error mapInteger(T &Value, const Twine &Comment = "") {
97
3.21k
    if (isStreaming()) {
98
175
      emitComment(Comment);
99
175
      Streamer->EmitIntValue((int)Value, sizeof(T));
100
175
      incrStreamedLen(sizeof(T));
101
175
      return Error::success();
102
175
    }
103
3.03k
104
3.03k
    if (isWriting())
105
377
      return Writer->writeInteger(Value);
106
2.65k
107
2.65k
    return Reader->readInteger(Value);
108
2.65k
  }
109
110
32.1k
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
32.1k
    if (!isStreaming() && 
sizeof(Value) > maxFieldLength()18.9k
)
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
32.1k
114
32.1k
    using U = typename std::underlying_type<T>::type;
115
32.1k
    U X;
116
32.1k
117
32.1k
    if (isWriting() || 
isStreaming()29.3k
)
118
16.0k
      X = static_cast<U>(Value);
119
32.1k
120
32.1k
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
32.1k
123
32.1k
    if (isReading())
124
16.1k
      Value = static_cast<T>(X);
125
32.1k
126
32.1k
    return Error::success();
127
32.1k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::ThunkOrdinal>(llvm::codeview::ThunkOrdinal&, llvm::Twine const&)
Line
Count
Source
110
14
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
14
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
14
114
14
    using U = typename std::underlying_type<T>::type;
115
14
    U X;
116
14
117
14
    if (isWriting() || 
isStreaming()5
)
118
9
      X = static_cast<U>(Value);
119
14
120
14
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
14
123
14
    if (isReading())
124
5
      Value = static_cast<T>(X);
125
14
126
14
    return Error::success();
127
14
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::TrampolineType>(llvm::codeview::TrampolineType&, llvm::Twine const&)
Line
Count
Source
110
6
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
6
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
6
114
6
    using U = typename std::underlying_type<T>::type;
115
6
    U X;
116
6
117
6
    if (isWriting() || 
isStreaming()5
)
118
1
      X = static_cast<U>(Value);
119
6
120
6
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
6
123
6
    if (isReading())
124
5
      Value = static_cast<T>(X);
125
6
126
6
    return Error::success();
127
6
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::LocalSymFlags>(llvm::codeview::LocalSymFlags&, llvm::Twine const&)
Line
Count
Source
110
387
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
387
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
387
114
387
    using U = typename std::underlying_type<T>::type;
115
387
    U X;
116
387
117
387
    if (isWriting() || 
isStreaming()376
)
118
11
      X = static_cast<U>(Value);
119
387
120
387
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
387
123
387
    if (isReading())
124
376
      Value = static_cast<T>(X);
125
387
126
387
    return Error::success();
127
387
  }
Unexecuted instantiation: llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::ExportFlags>(llvm::codeview::ExportFlags&, llvm::Twine const&)
Unexecuted instantiation: llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::CompileSym2Flags>(llvm::codeview::CompileSym2Flags&, llvm::Twine const&)
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::CPUType>(llvm::codeview::CPUType&, llvm::Twine const&)
Line
Count
Source
110
489
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
489
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
489
114
489
    using U = typename std::underlying_type<T>::type;
115
489
    U X;
116
489
117
489
    if (isWriting() || 
isStreaming()333
)
118
156
      X = static_cast<U>(Value);
119
489
120
489
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
489
123
489
    if (isReading())
124
333
      Value = static_cast<T>(X);
125
489
126
489
    return Error::success();
127
489
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::CompileSym3Flags>(llvm::codeview::CompileSym3Flags&, llvm::Twine const&)
Line
Count
Source
110
489
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
489
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
489
114
489
    using U = typename std::underlying_type<T>::type;
115
489
    U X;
116
489
117
489
    if (isWriting() || 
isStreaming()333
)
118
156
      X = static_cast<U>(Value);
119
489
120
489
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
489
123
489
    if (isReading())
124
333
      Value = static_cast<T>(X);
125
489
126
489
    return Error::success();
127
489
  }
Unexecuted instantiation: llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::FrameCookieKind>(llvm::codeview::FrameCookieKind&, llvm::Twine const&)
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::FrameProcedureOptions>(llvm::codeview::FrameProcedureOptions&, llvm::Twine const&)
Line
Count
Source
110
386
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
386
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
386
114
386
    using U = typename std::underlying_type<T>::type;
115
386
    U X;
116
386
117
386
    if (isWriting() || 
isStreaming()334
)
118
52
      X = static_cast<U>(Value);
119
386
120
386
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
386
123
386
    if (isReading())
124
334
      Value = static_cast<T>(X);
125
386
126
386
    return Error::success();
127
386
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::RegisterId>(llvm::codeview::RegisterId&, llvm::Twine const&)
Line
Count
Source
110
46
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
46
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
46
114
46
    using U = typename std::underlying_type<T>::type;
115
46
    U X;
116
46
117
46
    if (isWriting() || 
isStreaming()25
)
118
21
      X = static_cast<U>(Value);
119
46
120
46
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
46
123
46
    if (isReading())
124
25
      Value = static_cast<T>(X);
125
46
126
46
    return Error::success();
127
46
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::PublicSymFlags>(llvm::codeview::PublicSymFlags&, llvm::Twine const&)
Line
Count
Source
110
571
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
571
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
571
114
571
    using U = typename std::underlying_type<T>::type;
115
571
    U X;
116
571
117
571
    if (isWriting() || 
isStreaming()302
)
118
269
      X = static_cast<U>(Value);
119
571
120
571
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
571
123
571
    if (isReading())
124
302
      Value = static_cast<T>(X);
125
571
126
571
    return Error::success();
127
571
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::ProcSymFlags>(llvm::codeview::ProcSymFlags&, llvm::Twine const&)
Line
Count
Source
110
419
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
419
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
419
114
419
    using U = typename std::underlying_type<T>::type;
115
419
    U X;
116
419
117
419
    if (isWriting() || 
isStreaming()363
)
118
56
      X = static_cast<U>(Value);
119
419
120
419
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
419
123
419
    if (isReading())
124
363
      Value = static_cast<T>(X);
125
419
126
419
    return Error::success();
127
419
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::TypeLeafKind>(llvm::codeview::TypeLeafKind&, llvm::Twine const&)
Line
Count
Source
110
11.8k
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
11.8k
    if (!isStreaming() && 
sizeof(Value) > maxFieldLength()0
)
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
11.8k
114
11.8k
    using U = typename std::underlying_type<T>::type;
115
11.8k
    U X;
116
11.8k
117
11.8k
    if (isWriting() || isStreaming())
118
11.8k
      X = static_cast<U>(Value);
119
11.8k
120
11.8k
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
11.8k
123
11.8k
    if (isReading())
124
0
      Value = static_cast<T>(X);
125
11.8k
126
11.8k
    return Error::success();
127
11.8k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::ModifierOptions>(llvm::codeview::ModifierOptions&, llvm::Twine const&)
Line
Count
Source
110
520
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
520
    if (!isStreaming() && 
sizeof(Value) > maxFieldLength()473
)
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
520
114
520
    using U = typename std::underlying_type<T>::type;
115
520
    U X;
116
520
117
520
    if (isWriting() || 
isStreaming()447
)
118
120
      X = static_cast<U>(Value);
119
520
120
520
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
520
123
520
    if (isReading())
124
400
      Value = static_cast<T>(X);
125
520
126
520
    return Error::success();
127
520
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::CallingConvention>(llvm::codeview::CallingConvention&, llvm::Twine const&)
Line
Count
Source
110
4.31k
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
4.31k
    if (!isStreaming() && 
sizeof(Value) > maxFieldLength()3.91k
)
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
4.31k
114
4.31k
    using U = typename std::underlying_type<T>::type;
115
4.31k
    U X;
116
4.31k
117
4.31k
    if (isWriting() || 
isStreaming()3.63k
)
118
1.08k
      X = static_cast<U>(Value);
119
4.31k
120
4.31k
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
4.31k
123
4.31k
    if (isReading())
124
3.23k
      Value = static_cast<T>(X);
125
4.31k
126
4.31k
    return Error::success();
127
4.31k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::FunctionOptions>(llvm::codeview::FunctionOptions&, llvm::Twine const&)
Line
Count
Source
110
4.31k
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
4.31k
    if (!isStreaming() && 
sizeof(Value) > maxFieldLength()3.91k
)
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
4.31k
114
4.31k
    using U = typename std::underlying_type<T>::type;
115
4.31k
    U X;
116
4.31k
117
4.31k
    if (isWriting() || 
isStreaming()3.63k
)
118
1.08k
      X = static_cast<U>(Value);
119
4.31k
120
4.31k
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
4.31k
123
4.31k
    if (isReading())
124
3.23k
      Value = static_cast<T>(X);
125
4.31k
126
4.31k
    return Error::success();
127
4.31k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::PointerToMemberRepresentation>(llvm::codeview::PointerToMemberRepresentation&, llvm::Twine const&)
Line
Count
Source
110
164
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
164
    if (!isStreaming() && 
sizeof(Value) > maxFieldLength()132
)
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
164
114
164
    using U = typename std::underlying_type<T>::type;
115
164
    U X;
116
164
117
164
    if (isWriting() || 
isStreaming()130
)
118
66
      X = static_cast<U>(Value);
119
164
120
164
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
164
123
164
    if (isReading())
124
98
      Value = static_cast<T>(X);
125
164
126
164
    return Error::success();
127
164
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::ClassOptions>(llvm::codeview::ClassOptions&, llvm::Twine const&)
Line
Count
Source
110
8.21k
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
8.21k
    if (!isStreaming() && 
sizeof(Value) > maxFieldLength()7.74k
)
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
8.21k
114
8.21k
    using U = typename std::underlying_type<T>::type;
115
8.21k
    U X;
116
8.21k
117
8.21k
    if (isWriting() || 
isStreaming()7.54k
)
118
1.14k
      X = static_cast<U>(Value);
119
8.21k
120
8.21k
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
8.21k
123
8.21k
    if (isReading())
124
7.07k
      Value = static_cast<T>(X);
125
8.21k
126
8.21k
    return Error::success();
127
8.21k
  }
llvm::Error llvm::codeview::CodeViewRecordIO::mapEnum<llvm::codeview::LabelType>(llvm::codeview::LabelType&, llvm::Twine const&)
Line
Count
Source
110
1
  template <typename T> Error mapEnum(T &Value, const Twine &Comment = "") {
111
1
    if (!isStreaming() && sizeof(Value) > maxFieldLength())
112
0
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
113
1
114
1
    using U = typename std::underlying_type<T>::type;
115
1
    U X;
116
1
117
1
    if (isWriting() || isStreaming())
118
0
      X = static_cast<U>(Value);
119
1
120
1
    if (auto EC = mapInteger(X, Comment))
121
0
      return EC;
122
1
123
1
    if (isReading())
124
1
      Value = static_cast<T>(X);
125
1
126
1
    return Error::success();
127
1
  }
128
129
  Error mapEncodedInteger(int64_t &Value, const Twine &Comment = "");
130
  Error mapEncodedInteger(uint64_t &Value, const Twine &Comment = "");
131
  Error mapEncodedInteger(APSInt &Value, const Twine &Comment = "");
132
  Error mapStringZ(StringRef &Value, const Twine &Comment = "");
133
  Error mapGuid(GUID &Guid, const Twine &Comment = "");
134
135
  Error mapStringZVectorZ(std::vector<StringRef> &Value,
136
                          const Twine &Comment = "");
137
138
  template <typename SizeType, typename T, typename ElementMapper>
139
  Error mapVectorN(T &Items, const ElementMapper &Mapper,
140
3.47k
                   const Twine &Comment = "") {
141
3.47k
    SizeType Size;
142
3.47k
    if (isStreaming()) {
143
457
      Size = static_cast<SizeType>(Items.size());
144
457
      emitComment(Comment);
145
457
      Streamer->EmitIntValue(Size, sizeof(Size));
146
457
      incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
147
457
148
1.12k
      for (auto &X : Items) {
149
1.12k
        if (auto EC = Mapper(*this, X))
150
0
          return EC;
151
1.12k
      }
152
3.02k
    } else if (isWriting()) {
153
888
      Size = static_cast<SizeType>(Items.size());
154
888
      if (auto EC = Writer->writeInteger(Size))
155
0
        return EC;
156
888
157
1.63k
      
for (auto &X : Items)888
{
158
1.63k
        if (auto EC = Mapper(*this, X))
159
0
          return EC;
160
1.63k
      }
161
2.13k
    } else {
162
2.13k
      if (auto EC = Reader->readInteger(Size))
163
0
        return EC;
164
6.75k
      
for (SizeType I = 0; 2.13k
I < Size;
++I4.61k
) {
165
4.61k
        typename T::value_type Item;
166
4.61k
        if (auto EC = Mapper(*this, Item))
167
0
          return EC;
168
4.61k
        Items.push_back(Item);
169
4.61k
      }
170
2.13k
    }
171
3.47k
172
3.47k
    return Error::success();
173
3.47k
  }
SymbolRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorN<unsigned int, std::__1::vector<llvm::codeview::TypeIndex, std::__1::allocator<llvm::codeview::TypeIndex> >, llvm::codeview::SymbolRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::SymbolKind>&, llvm::codeview::CallerSym&)::$_0>(std::__1::vector<llvm::codeview::TypeIndex, std::__1::allocator<llvm::codeview::TypeIndex> >&, llvm::codeview::SymbolRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::SymbolKind>&, llvm::codeview::CallerSym&)::$_0 const&, llvm::Twine const&)
Line
Count
Source
140
15
                   const Twine &Comment = "") {
141
15
    SizeType Size;
142
15
    if (isStreaming()) {
143
0
      Size = static_cast<SizeType>(Items.size());
144
0
      emitComment(Comment);
145
0
      Streamer->EmitIntValue(Size, sizeof(Size));
146
0
      incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
147
0
148
0
      for (auto &X : Items) {
149
0
        if (auto EC = Mapper(*this, X))
150
0
          return EC;
151
0
      }
152
15
    } else if (isWriting()) {
153
7
      Size = static_cast<SizeType>(Items.size());
154
7
      if (auto EC = Writer->writeInteger(Size))
155
0
        return EC;
156
7
157
13
      
for (auto &X : Items)7
{
158
13
        if (auto EC = Mapper(*this, X))
159
0
          return EC;
160
13
      }
161
8
    } else {
162
8
      if (auto EC = Reader->readInteger(Size))
163
0
        return EC;
164
17
      
for (SizeType I = 0; 8
I < Size;
++I9
) {
165
9
        typename T::value_type Item;
166
9
        if (auto EC = Mapper(*this, Item))
167
0
          return EC;
168
9
        Items.push_back(Item);
169
9
      }
170
8
    }
171
15
172
15
    return Error::success();
173
15
  }
SymbolRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorN<unsigned short, std::__1::vector<llvm::StringRef, std::__1::allocator<llvm::StringRef> >, llvm::codeview::SymbolRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::SymbolKind>&, llvm::codeview::AnnotationSym&)::$_1>(std::__1::vector<llvm::StringRef, std::__1::allocator<llvm::StringRef> >&, llvm::codeview::SymbolRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::SymbolKind>&, llvm::codeview::AnnotationSym&)::$_1 const&, llvm::Twine const&)
Line
Count
Source
140
3
                   const Twine &Comment = "") {
141
3
    SizeType Size;
142
3
    if (isStreaming()) {
143
0
      Size = static_cast<SizeType>(Items.size());
144
0
      emitComment(Comment);
145
0
      Streamer->EmitIntValue(Size, sizeof(Size));
146
0
      incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
147
0
148
0
      for (auto &X : Items) {
149
0
        if (auto EC = Mapper(*this, X))
150
0
          return EC;
151
0
      }
152
3
    } else if (isWriting()) {
153
1
      Size = static_cast<SizeType>(Items.size());
154
1
      if (auto EC = Writer->writeInteger(Size))
155
0
        return EC;
156
1
157
2
      
for (auto &X : Items)1
{
158
2
        if (auto EC = Mapper(*this, X))
159
0
          return EC;
160
2
      }
161
2
    } else {
162
2
      if (auto EC = Reader->readInteger(Size))
163
0
        return EC;
164
6
      
for (SizeType I = 0; 2
I < Size;
++I4
) {
165
4
        typename T::value_type Item;
166
4
        if (auto EC = Mapper(*this, Item))
167
0
          return EC;
168
4
        Items.push_back(Item);
169
4
      }
170
2
    }
171
3
172
3
    return Error::success();
173
3
  }
TypeRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorN<unsigned int, std::__1::vector<llvm::codeview::TypeIndex, std::__1::allocator<llvm::codeview::TypeIndex> >, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::ArgListRecord&)::$_0>(std::__1::vector<llvm::codeview::TypeIndex, std::__1::allocator<llvm::codeview::TypeIndex> >&, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::ArgListRecord&)::$_0 const&, llvm::Twine const&)
Line
Count
Source
140
2.46k
                   const Twine &Comment = "") {
141
2.46k
    SizeType Size;
142
2.46k
    if (isStreaming()) {
143
267
      Size = static_cast<SizeType>(Items.size());
144
267
      emitComment(Comment);
145
267
      Streamer->EmitIntValue(Size, sizeof(Size));
146
267
      incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
147
267
148
267
      for (auto &X : Items) {
149
178
        if (auto EC = Mapper(*this, X))
150
0
          return EC;
151
178
      }
152
2.19k
    } else if (isWriting()) {
153
617
      Size = static_cast<SizeType>(Items.size());
154
617
      if (auto EC = Writer->writeInteger(Size))
155
0
        return EC;
156
617
157
617
      for (auto &X : Items) {
158
450
        if (auto EC = Mapper(*this, X))
159
0
          return EC;
160
450
      }
161
1.57k
    } else {
162
1.57k
      if (auto EC = Reader->readInteger(Size))
163
0
        return EC;
164
3.65k
      
for (SizeType I = 0; 1.57k
I < Size;
++I2.08k
) {
165
2.08k
        typename T::value_type Item;
166
2.08k
        if (auto EC = Mapper(*this, Item))
167
0
          return EC;
168
2.08k
        Items.push_back(Item);
169
2.08k
      }
170
1.57k
    }
171
2.46k
172
2.46k
    return Error::success();
173
2.46k
  }
TypeRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorN<unsigned int, std::__1::vector<llvm::codeview::TypeIndex, std::__1::allocator<llvm::codeview::TypeIndex> >, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::StringListRecord&)::$_1>(std::__1::vector<llvm::codeview::TypeIndex, std::__1::allocator<llvm::codeview::TypeIndex> >&, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::StringListRecord&)::$_1 const&, llvm::Twine const&)
Line
Count
Source
140
90
                   const Twine &Comment = "") {
141
90
    SizeType Size;
142
90
    if (isStreaming()) {
143
0
      Size = static_cast<SizeType>(Items.size());
144
0
      emitComment(Comment);
145
0
      Streamer->EmitIntValue(Size, sizeof(Size));
146
0
      incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
147
0
148
0
      for (auto &X : Items) {
149
0
        if (auto EC = Mapper(*this, X))
150
0
          return EC;
151
0
      }
152
90
    } else if (isWriting()) {
153
37
      Size = static_cast<SizeType>(Items.size());
154
37
      if (auto EC = Writer->writeInteger(Size))
155
0
        return EC;
156
37
157
46
      
for (auto &X : Items)37
{
158
46
        if (auto EC = Mapper(*this, X))
159
0
          return EC;
160
46
      }
161
53
    } else {
162
53
      if (auto EC = Reader->readInteger(Size))
163
0
        return EC;
164
117
      
for (SizeType I = 0; 53
I < Size;
++I64
) {
165
64
        typename T::value_type Item;
166
64
        if (auto EC = Mapper(*this, Item))
167
0
          return EC;
168
64
        Items.push_back(Item);
169
64
      }
170
53
    }
171
90
172
90
    return Error::success();
173
90
  }
TypeRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorN<unsigned short, llvm::SmallVector<llvm::codeview::TypeIndex, 5u>, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::BuildInfoRecord&)::$_3>(llvm::SmallVector<llvm::codeview::TypeIndex, 5u>&, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::BuildInfoRecord&)::$_3 const&, llvm::Twine const&)
Line
Count
Source
140
908
                   const Twine &Comment = "") {
141
908
    SizeType Size;
142
908
    if (isStreaming()) {
143
190
      Size = static_cast<SizeType>(Items.size());
144
190
      emitComment(Comment);
145
190
      Streamer->EmitIntValue(Size, sizeof(Size));
146
190
      incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
147
190
148
950
      for (auto &X : Items) {
149
950
        if (auto EC = Mapper(*this, X))
150
0
          return EC;
151
950
      }
152
718
    } else if (isWriting()) {
153
226
      Size = static_cast<SizeType>(Items.size());
154
226
      if (auto EC = Writer->writeInteger(Size))
155
0
        return EC;
156
226
157
1.12k
      
for (auto &X : Items)226
{
158
1.12k
        if (auto EC = Mapper(*this, X))
159
0
          return EC;
160
1.12k
      }
161
492
    } else {
162
492
      if (auto EC = Reader->readInteger(Size))
163
0
        return EC;
164
2.95k
      
for (SizeType I = 0; 492
I < Size;
++I2.46k
) {
165
2.46k
        typename T::value_type Item;
166
2.46k
        if (auto EC = Mapper(*this, Item))
167
0
          return EC;
168
2.46k
        Items.push_back(Item);
169
2.46k
      }
170
492
    }
171
908
172
908
    return Error::success();
173
908
  }
174
175
  template <typename T, typename ElementMapper>
176
  Error mapVectorTail(T &Items, const ElementMapper &Mapper,
177
915
                      const Twine &Comment = "") {
178
915
    emitComment(Comment);
179
915
    if (isStreaming() || 
isWriting()907
) {
180
164
      for (auto &Item : Items) {
181
164
        if (auto EC = Mapper(*this, Item))
182
0
          return EC;
183
164
      }
184
831
    } else {
185
831
      typename T::value_type Field;
186
831
      // Stop when we run out of bytes or we hit record padding bytes.
187
1.92k
      while (!Reader->empty() && 
Reader->peek() < 0xf01.10k
/* LF_PAD0 */) {
188
1.09k
        if (auto EC = Mapper(*this, Field))
189
0
          return EC;
190
1.09k
        Items.push_back(Field);
191
1.09k
      }
192
831
    }
193
915
    return Error::success();
194
915
  }
SymbolRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorTail<std::__1::vector<llvm::codeview::LocalVariableAddrGap, std::__1::allocator<llvm::codeview::LocalVariableAddrGap> >, (anonymous namespace)::MapGap>(std::__1::vector<llvm::codeview::LocalVariableAddrGap, std::__1::allocator<llvm::codeview::LocalVariableAddrGap> >&, (anonymous namespace)::MapGap const&, llvm::Twine const&)
Line
Count
Source
177
400
                      const Twine &Comment = "") {
178
400
    emitComment(Comment);
179
400
    if (isStreaming() || isWriting()) {
180
13
      for (auto &Item : Items) {
181
1
        if (auto EC = Mapper(*this, Item))
182
0
          return EC;
183
1
      }
184
387
    } else {
185
387
      typename T::value_type Field;
186
387
      // Stop when we run out of bytes or we hit record padding bytes.
187
391
      while (!Reader->empty() && 
Reader->peek() < 0xf04
/* LF_PAD0 */) {
188
4
        if (auto EC = Mapper(*this, Field))
189
0
          return EC;
190
4
        Items.push_back(Field);
191
4
      }
192
387
    }
193
400
    return Error::success();
194
400
  }
TypeRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorTail<std::__1::vector<llvm::StringRef, std::__1::allocator<llvm::StringRef> >, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::VFTableRecord&)::$_2>(std::__1::vector<llvm::StringRef, std::__1::allocator<llvm::StringRef> >&, llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::VFTableRecord&)::$_2 const&, llvm::Twine const&)
Line
Count
Source
177
17
                      const Twine &Comment = "") {
178
17
    emitComment(Comment);
179
17
    if (isStreaming() || isWriting()) {
180
10
      for (auto &Item : Items) {
181
10
        if (auto EC = Mapper(*this, Item))
182
0
          return EC;
183
10
      }
184
11
    } else {
185
11
      typename T::value_type Field;
186
11
      // Stop when we run out of bytes or we hit record padding bytes.
187
39
      while (!Reader->empty() && Reader->peek() < 0xf0 /* LF_PAD0 */) {
188
28
        if (auto EC = Mapper(*this, Field))
189
0
          return EC;
190
28
        Items.push_back(Field);
191
28
      }
192
11
    }
193
17
    return Error::success();
194
17
  }
TypeRecordMapping.cpp:llvm::Error llvm::codeview::CodeViewRecordIO::mapVectorTail<std::__1::vector<llvm::codeview::OneMethodRecord, std::__1::allocator<llvm::codeview::OneMethodRecord> >, (anonymous namespace)::MapOneMethodRecord>(std::__1::vector<llvm::codeview::OneMethodRecord, std::__1::allocator<llvm::codeview::OneMethodRecord> >&, (anonymous namespace)::MapOneMethodRecord const&, llvm::Twine const&)
Line
Count
Source
177
498
                      const Twine &Comment = "") {
178
498
    emitComment(Comment);
179
498
    if (isStreaming() || 
isWriting()490
) {
180
153
      for (auto &Item : Items) {
181
153
        if (auto EC = Mapper(*this, Item))
182
0
          return EC;
183
153
      }
184
433
    } else {
185
433
      typename T::value_type Field;
186
433
      // Stop when we run out of bytes or we hit record padding bytes.
187
1.49k
      while (!Reader->empty() && 
Reader->peek() < 0xf01.06k
/* LF_PAD0 */) {
188
1.06k
        if (auto EC = Mapper(*this, Field))
189
0
          return EC;
190
1.06k
        Items.push_back(Field);
191
1.06k
      }
192
433
    }
193
498
    return Error::success();
194
498
  }
195
196
  Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes, const Twine &Comment = "");
197
  Error mapByteVectorTail(std::vector<uint8_t> &Bytes,
198
                          const Twine &Comment = "");
199
200
  Error padToAlignment(uint32_t Align);
201
  Error skipPadding();
202
203
14.9k
  uint64_t getStreamedLen() {
204
14.9k
    if (isStreaming())
205
14.9k
      return StreamedLen;
206
0
    return 0;
207
0
  }
208
209
private:
210
  void emitEncodedSignedInteger(const int64_t &Value,
211
                                const Twine &Comment = "");
212
  void emitEncodedUnsignedInteger(const uint64_t &Value,
213
                                  const Twine &Comment = "");
214
  Error writeEncodedSignedInteger(const int64_t &Value);
215
  Error writeEncodedUnsignedInteger(const uint64_t &Value);
216
217
59.1k
  void incrStreamedLen(const uint64_t &Len) {
218
59.1k
    if (isStreaming())
219
59.1k
      StreamedLen += Len;
220
59.1k
  }
221
222
3.40k
  void resetStreamedLen() {
223
3.40k
    if (isStreaming())
224
3.40k
      StreamedLen = 4; // The record prefix is 4 bytes long
225
3.40k
  }
226
227
60.1k
  void emitComment(const Twine &Comment) {
228
60.1k
    if (isStreaming()) {
229
59.1k
      Twine TComment(Comment);
230
59.1k
      if (!TComment.isTriviallyEmpty())
231
47.6k
        Streamer->AddComment(TComment);
232
59.1k
    }
233
60.1k
  }
234
235
  struct RecordLimit {
236
    uint32_t BeginOffset;
237
    Optional<uint32_t> MaxLength;
238
239
49.6k
    Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
240
49.6k
      if (!MaxLength.hasValue())
241
12.4k
        return None;
242
37.1k
      assert(CurrentOffset >= BeginOffset);
243
37.1k
244
37.1k
      uint32_t BytesUsed = CurrentOffset - BeginOffset;
245
37.1k
      if (BytesUsed >= *MaxLength)
246
0
        return 0;
247
37.1k
      return *MaxLength - BytesUsed;
248
37.1k
    }
249
  };
250
251
  SmallVector<RecordLimit, 2> Limits;
252
253
  BinaryStreamReader *Reader = nullptr;
254
  BinaryStreamWriter *Writer = nullptr;
255
  CodeViewRecordStreamer *Streamer = nullptr;
256
  uint64_t StreamedLen = 0;
257
};
258
259
} // end namespace codeview
260
} // end namespace llvm
261
262
#endif // LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H