LLVM: lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp Source File (original) (raw)

2

3using namespace llvm;

5

6namespace {

7struct ContinuationRecord {

8 ulittle16_t Kind{uint16_t(TypeLeafKind::LF_INDEX)};

11};

12

13struct SegmentInjection {

14 SegmentInjection(TypeLeafKind Kind) { Prefix.RecordKind = Kind; }

15

16 ContinuationRecord Cont;

17 RecordPrefix Prefix;

18};

19}

20

24 return;

25

26 int PaddingBytes = 4 - Align;

27 while (PaddingBytes > 0) {

28 uint8_t Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);

30 --PaddingBytes;

31 }

32}

33

34static SegmentInjection InjectFieldList(TypeLeafKind::LF_FIELDLIST);

36

40

45

47 : SegmentWriter(Buffer), Mapping(SegmentWriter) {}

48

50

53 Kind = RecordKind;

54 Buffer.clear();

55 SegmentWriter.setOffset(0);

56 SegmentOffsets.clear();

57 SegmentOffsets.push_back(0);

58 assert(SegmentWriter.getOffset() == 0);

59 assert(SegmentWriter.getLength() == 0);

60

61 const SegmentInjection *FLI =

65 const uint8_t *FLIB = reinterpret_cast<const uint8_t *>(FLI);

66 InjectedSegmentBytes =

68

69

73

74 cantFail(SegmentWriter.writeObject(Prefix));

75}

76

77template

80

81 uint32_t OriginalOffset = SegmentWriter.getOffset();

84

85

86

88

89

90 cantFail(Mapping.visitMemberBegin(CVMR));

92 cantFail(Mapping.visitMemberEnd(CVMR));

93

94

96 assert(getCurrentSegmentLength() % 4 == 0);

97

98

99

100

101

102

104

105

106

107 uint32_t MemberLength = SegmentWriter.getOffset() - OriginalOffset;

108 (void) MemberLength;

109 insertSegmentEnd(OriginalOffset);

110

111

112

113

114 assert(getCurrentSegmentLength() == MemberLength + sizeof(RecordPrefix));

115 }

116

117 assert(getCurrentSegmentLength() % 4 == 0);

119}

120

121uint32_t ContinuationRecordBuilder::getCurrentSegmentLength() const {

122 return SegmentWriter.getOffset() - SegmentOffsets.back();

123}

124

125void ContinuationRecordBuilder::insertSegmentEnd(uint32_t Offset) {

126 uint32_t SegmentBegin = SegmentOffsets.back();

127 (void)SegmentBegin;

130

131

132

133

135

137 uint32_t SegmentLength = NewSegmentBegin - SegmentOffsets.back();

138 (void) SegmentLength;

139

140 assert(SegmentLength % 4 == 0);

142 SegmentOffsets.push_back(NewSegmentBegin);

143

144

147}

148

149CVType ContinuationRecordBuilder::createSegmentRecord(

150 uint32_t OffBegin, uint32_t OffEnd, std::optional RefersTo) {

151 assert(OffEnd - OffBegin <= USHRT_MAX);

152

154 Data = Data.slice(OffBegin, OffEnd - OffBegin);

155

156

157

160

161 if (RefersTo) {

163 ContinuationRecord *CR =

164 reinterpret_cast<ContinuationRecord *>(Continuation.data());

165 assert(CR->Kind == TypeLeafKind::LF_INDEX);

166 assert(CR->IndexRef == 0xB0C0B0C0);

167 CR->IndexRef = RefersTo->getIndex();

168 }

169

171}

172

175 CVType Type(&Prefix, sizeof(Prefix));

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224 std::vector Types;

225 Types.reserve(SegmentOffsets.size());

226

227 ArrayRef SO = SegmentOffsets;

228

229 uint32_t End = SegmentWriter.getOffset();

230

231 std::optional RefersTo;

233 Types.push_back(createSegmentRecord(Offset, End, RefersTo));

234

236 RefersTo = Index++;

237 }

238

239 Kind.reset();

240 return Types;

241}

242

243

244

245#define TYPE_RECORD(EnumName, EnumVal, Name)

246#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)

247#define MEMBER_RECORD(EnumName, EnumVal, Name) \

248 template LLVM_ABI void \

249 llvm::codeview::ContinuationRecordBuilder::writeMemberType( \

250 Name##Record &Record);

251#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)

252#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static constexpr uint32_t ContinuationLength

Definition ContinuationRecordBuilder.cpp:37

static TypeLeafKind getTypeLeafKind(ContinuationRecordKind CK)

Definition ContinuationRecordBuilder.cpp:41

static constexpr uint32_t MaxSegmentLength

Definition ContinuationRecordBuilder.cpp:38

static SegmentInjection InjectFieldList(TypeLeafKind::LF_FIELDLIST)

static SegmentInjection InjectMethodOverloadList(TypeLeafKind::LF_METHODLIST)

static void addPadding(BinaryStreamWriter &Writer)

Definition ContinuationRecordBuilder.cpp:21

FunctionLoweringInfo::StatepointRelocationRecord RecordType

MutableArrayRef< uint8_t > data()

void insert(uint64_t Offset, ArrayRef< uint8_t > Bytes)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Provides write only access to a subclass of WritableBinaryStream.

uint64_t getOffset() const

Error writeInteger(T Value)

Write the integer Value to the underlying stream in the specified endianness.

uint64_t bytesRemaining() const

uint64_t getLength() const

void setOffset(uint64_t Off)

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

void push_back(const T &Elt)

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM_ABI void begin(ContinuationRecordKind RecordKind)

Definition ContinuationRecordBuilder.cpp:51

LLVM_ABI std::vector< CVType > end(TypeIndex Index)

Definition ContinuationRecordBuilder.cpp:173

LLVM_ABI ~ContinuationRecordBuilder()

LLVM_ABI ContinuationRecordBuilder()

Definition ContinuationRecordBuilder.cpp:46

void writeMemberType(RecordType &Record)

Definition ContinuationRecordBuilder.cpp:78

CVRecord< TypeLeafKind > CVType

TypeLeafKind

Duplicate copy of the above enum, but using the official CV names.

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t

This is an optimization pass for GlobalISel generic memory operations.

auto reverse(ContainerTy &&C)

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

This struct is a compact representation of a valid (non-zero power of two) alignment.