LLVM: lib/ObjectYAML/GOFFEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

19

20using namespace llvm;

21

22namespace {

23

24

25enum {

26

27 Rec_Continued = 1,

28

29

30 Rec_Continuation = 1 << (8 - 6 - 1),

31};

32

33template struct BinaryBeImpl {

35 BinaryBeImpl(ValueType V) : Value(V) {}

36};

37

38template

40 char Buffer[sizeof(BBE.Value)];

43 OS.write(Buffer, sizeof(BBE.Value));

44 return OS;

45}

46

47template BinaryBeImpl binaryBe(ValueType V) {

48 return BinaryBeImpl(V);

49}

50

51struct ZerosImpl {

52 size_t NumBytes;

53};

54

57 return OS;

58}

59

60ZerosImpl zeros(const size_t NumBytes) { return ZerosImpl{NumBytes}; }

61

62

63

64

65

66

68public:

69 explicit GOFFOstream(raw_ostream &OS)

70 : OS(OS), LogicalRecords(0), RemainingSize(0), NewLogicalRecord(false) {

72 }

73

74 ~GOFFOstream() override { finalize(); }

75

77 fillRecord();

78 CurrentType = Type;

79 RemainingSize = Size;

82 NewLogicalRecord = true;

83 ++LogicalRecords;

84 }

85

86 void finalize() { fillRecord(); }

87

88 uint32_t logicalRecords() { return LogicalRecords; }

89

90private:

91

92 raw_ostream &OS;

93

94

95 uint32_t LogicalRecords;

96

97

98 size_t RemainingSize;

99

100

102

103

104 bool NewLogicalRecord;

105

106

107

108

109 size_t bytesToNextPhysicalRecord() {

112 }

113

114

115

117 size_t RemainingSize,

118 uint8_t Flags = Rec_Continuation) {

119 uint8_t TypeAndFlags = Flags | (Type << 4);

121 TypeAndFlags |= Rec_Continued;

122 OS << binaryBe(static_cast(GOFF::PTVPrefix))

123 << binaryBe(static_cast<unsigned char>(TypeAndFlags))

124 << binaryBe(static_cast<unsigned char>(0));

125 }

126

127

128 void fillRecord() {

129 assert((GetNumBytesInBuffer() <= RemainingSize) &&

130 "More bytes in buffer than expected");

131 size_t Remains = RemainingSize - GetNumBytesInBuffer();

132 if (Remains) {

134 "Attempting to fill more than one physical record");

136 }

137 flush();

138 assert(RemainingSize == 0 && "Not fully flushed");

139 assert(GetNumBytesInBuffer() == 0 && "Buffer not fully empty");

140 }

141

142

143 void write_impl(const char *Ptr, size_t Size) override {

144 assert((RemainingSize >= Size) && "Attempt to write too much data");

145 assert(RemainingSize && "Logical record overflow");

147 writeRecordPrefix(OS, CurrentType, RemainingSize,

148 NewLogicalRecord ? 0 : Rec_Continuation);

149 NewLogicalRecord = false;

150 }

151 assert(!NewLogicalRecord &&

152 "New logical record not on physical record boundary");

153

154 size_t Idx = 0;

155 while (Size > 0) {

156 size_t BytesToWrite = bytesToNextPhysicalRecord();

157 if (BytesToWrite > Size)

158 BytesToWrite = Size;

159 OS.write(Ptr + Idx, BytesToWrite);

160 Idx += BytesToWrite;

161 Size -= BytesToWrite;

162 RemainingSize -= BytesToWrite;

164 writeRecordPrefix(OS, CurrentType, RemainingSize);

165 }

166 }

167 }

168

169

170

171 uint64_t current_pos() const override { return OS.tell(); }

172};

173

174class GOFFState {

175 void writeHeader(GOFFYAML::FileHeader &FileHdr);

176 void writeEnd();

177

179 ErrHandler(Msg);

180 HasError = true;

181 }

182

183 GOFFState(raw_ostream &OS, GOFFYAML::Object &Doc,

185 : GW(OS), Doc(Doc), ErrHandler(ErrHandler), HasError(false) {}

186

187 ~GOFFState() { GW.finalize(); }

188

189 bool writeObject();

190

191public:

192 static bool writeGOFF(raw_ostream &OS, GOFFYAML::Object &Doc,

194

195private:

196 GOFFOstream GW;

197 GOFFYAML::Object &Doc;

199 bool HasError;

200};

201

203 SmallString<16> CCSIDName;

204 if (std::error_code EC =

207 if (CCSIDName.size() > 16) {

208 reportError("CharacterSetName too long");

209 CCSIDName.resize(16);

210 }

211 SmallString<16> LangProd;

215 if (LangProd.size() > 16) {

216 reportError("LanguageProductIdentifier too long");

218 }

219

223 << zeros(2)

224 << binaryBe(FileHdr.CCSID)

225 << CCSIDName

226 << zeros(16 - CCSIDName.size())

227 << LangProd

228 << zeros(16 - LangProd.size())

230

231 uint16_t ModPropLen = 0;

233 ModPropLen = 3;

235 ModPropLen = 2;

236 if (ModPropLen) {

237 GW << binaryBe(ModPropLen) << zeros(6);

238 if (ModPropLen >= 2)

239 GW << binaryBe(FileHdr.InternalCCSID.value_or(0));

240 if (ModPropLen >= 3)

242 }

243}

244

245void GOFFState::writeEnd() {

247 GW << binaryBe(uint8_t(0))

248 << binaryBe(uint8_t(0))

249 << zeros(3)

250 << binaryBe(GW.logicalRecords());

251

252 GW.finalize();

253}

254

255bool GOFFState::writeObject() {

256 writeHeader(Doc.Header);

257 if (HasError)

258 return false;

259 writeEnd();

260 return true;

261}

262

263bool GOFFState::writeGOFF(raw_ostream &OS, GOFFYAML::Object &Doc,

265 GOFFState State(OS, Doc, ErrHandler);

266 return State.writeObject();

267}

268}

269

270namespace llvm {

271namespace yaml {

272

275 return GOFFState::writeGOFF(Out, Doc, ErrHandler);

276}

277

278}

279}

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

Function Alias Analysis false

static Error reportError(StringRef Message)

zeros_impl< sizeof(T)> zeros(const T &)

This file provides utility functions for converting between EBCDIC-1047 and UTF-8.

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & write_zeros(unsigned NumZeros)

write_zeros - Insert 'NumZeros' nulls.

raw_ostream & write(unsigned char C)

LLVM_ABI std::error_code convertToEBCDIC(StringRef Source, SmallVectorImpl< char > &Result)

constexpr uint8_t PayloadLength

constexpr uint8_t PTVPrefix

Prefix byte on every record. This indicates GOFF format.

constexpr uint8_t RecordLength

Length of the parts of a physical GOFF record.

void write(void *memory, value_type value, endianness endian)

Write a value to memory with a particular endianness.

LLVM_ABI bool yaml2goff(GOFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH)

Definition GOFFEmitter.cpp:273

llvm::function_ref< void(const Twine &Msg)> ErrorHandler

This is an optimization pass for GlobalISel generic memory operations.

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

PointerUnion< const Value *, const PseudoSourceValue * > ValueType

Common declarations for yaml2obj.