1//===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===//
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// This file defines classes for handling the YAML representation of wasm.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ObjectYAML/WasmYAML.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/Casting.h"
16#include "llvm/Support/ErrorHandling.h"
17#include "llvm/Support/YAMLTraits.h"
18
19namespace llvm {
20
21namespace WasmYAML {
22
23// Declared here rather than in the header to comply with:
24// http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers
25Section::~Section() = default;
26
27} // end namespace WasmYAML
28
29namespace yaml {
30
31void MappingTraits<WasmYAML::FileHeader>::mapping(
32    IO &IO, WasmYAML::FileHeader &FileHdr) {
33  IO.mapRequired("Version", FileHdr.Version);
34}
35
36void MappingTraits<WasmYAML::Object>::mapping(IO &IO,
37                                              WasmYAML::Object &Object) {
38  IO.setContext(&Object);
39  IO.mapTag("!WASM", true);
40  IO.mapRequired("FileHeader", Object.Header);
41  IO.mapOptional("Sections", Object.Sections);
42  IO.setContext(nullptr);
43}
44
45static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) {
46  IO.mapRequired("Type", Section.Type);
47  IO.mapOptional("Relocations", Section.Relocations);
48  IO.mapOptional("HeaderSecSizeEncodingLen", Section.HeaderSecSizeEncodingLen);
49}
50
51static void sectionMapping(IO &IO, WasmYAML::DylinkSection &Section) {
52  commonSectionMapping(IO, Section);
53  IO.mapRequired("Name", Section.Name);
54  IO.mapRequired("MemorySize", Section.MemorySize);
55  IO.mapRequired("MemoryAlignment", Section.MemoryAlignment);
56  IO.mapRequired("TableSize", Section.TableSize);
57  IO.mapRequired("TableAlignment", Section.TableAlignment);
58  IO.mapRequired("Needed", Section.Needed);
59  IO.mapOptional("ImportInfo", Section.ImportInfo);
60  IO.mapOptional("ExportInfo", Section.ExportInfo);
61}
62
63static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
64  commonSectionMapping(IO, Section);
65  IO.mapRequired("Name", Section.Name);
66  IO.mapOptional("FunctionNames", Section.FunctionNames);
67  IO.mapOptional("GlobalNames", Section.GlobalNames);
68  IO.mapOptional("DataSegmentNames", Section.DataSegmentNames);
69}
70
71static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
72  commonSectionMapping(IO, Section);
73  IO.mapRequired("Name", Section.Name);
74  IO.mapRequired("Version", Section.Version);
75  IO.mapOptional("SymbolTable", Section.SymbolTable);
76  IO.mapOptional("SegmentInfo", Section.SegmentInfos);
77  IO.mapOptional("InitFunctions", Section.InitFunctions);
78  IO.mapOptional("Comdats", Section.Comdats);
79}
80
81static void sectionMapping(IO &IO, WasmYAML::ProducersSection &Section) {
82  commonSectionMapping(IO, Section);
83  IO.mapRequired("Name", Section.Name);
84  IO.mapOptional("Languages", Section.Languages);
85  IO.mapOptional("Tools", Section.Tools);
86  IO.mapOptional("SDKs", Section.SDKs);
87}
88
89static void sectionMapping(IO &IO, WasmYAML::TargetFeaturesSection &Section) {
90  commonSectionMapping(IO, Section);
91  IO.mapRequired("Name", Section.Name);
92  IO.mapRequired("Features", Section.Features);
93}
94
95static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
96  commonSectionMapping(IO, Section);
97  IO.mapRequired("Name", Section.Name);
98  IO.mapRequired("Payload", Section.Payload);
99}
100
101static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) {
102  commonSectionMapping(IO, Section);
103  IO.mapOptional("Signatures", Section.Signatures);
104}
105
106static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) {
107  commonSectionMapping(IO, Section);
108  IO.mapOptional("Imports", Section.Imports);
109}
110
111static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) {
112  commonSectionMapping(IO, Section);
113  IO.mapOptional("FunctionTypes", Section.FunctionTypes);
114}
115
116static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) {
117  commonSectionMapping(IO, Section);
118  IO.mapOptional("Tables", Section.Tables);
119}
120
121static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) {
122  commonSectionMapping(IO, Section);
123  IO.mapOptional("Memories", Section.Memories);
124}
125
126static void sectionMapping(IO &IO, WasmYAML::TagSection &Section) {
127  commonSectionMapping(IO, Section);
128  IO.mapOptional("TagTypes", Section.TagTypes);
129}
130
131static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) {
132  commonSectionMapping(IO, Section);
133  IO.mapOptional("Globals", Section.Globals);
134}
135
136static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) {
137  commonSectionMapping(IO, Section);
138  IO.mapOptional("Exports", Section.Exports);
139}
140
141static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) {
142  commonSectionMapping(IO, Section);
143  IO.mapOptional("StartFunction", Section.StartFunction);
144}
145
146static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) {
147  commonSectionMapping(IO, Section);
148  IO.mapOptional("Segments", Section.Segments);
149}
150
151static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) {
152  commonSectionMapping(IO, Section);
153  IO.mapRequired("Functions", Section.Functions);
154}
155
156static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) {
157  commonSectionMapping(IO, Section);
158  IO.mapRequired("Segments", Section.Segments);
159}
160
161static void sectionMapping(IO &IO, WasmYAML::DataCountSection &Section) {
162  commonSectionMapping(IO, Section);
163  IO.mapRequired("Count", Section.Count);
164}
165
166void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
167    IO &IO, std::unique_ptr<WasmYAML::Section> &Section) {
168  WasmYAML::SectionType SectionType;
169  if (IO.outputting())
170    SectionType = Section->Type;
171  else
172    IO.mapRequired("Type", SectionType);
173
174  switch (SectionType) {
175  case wasm::WASM_SEC_CUSTOM: {
176    StringRef SectionName;
177    if (IO.outputting()) {
178      auto CustomSection = cast<WasmYAML::CustomSection>(Section.get());
179      SectionName = CustomSection->Name;
180    } else {
181      IO.mapRequired("Name", SectionName);
182    }
183    if (SectionName == "dylink" || SectionName == "dylink.0") {
184      if (!IO.outputting())
185        Section.reset(new WasmYAML::DylinkSection());
186      sectionMapping(IO, *cast<WasmYAML::DylinkSection>(Section.get()));
187    } else if (SectionName == "linking") {
188      if (!IO.outputting())
189        Section.reset(new WasmYAML::LinkingSection());
190      sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get()));
191    } else if (SectionName == "name") {
192      if (!IO.outputting())
193        Section.reset(new WasmYAML::NameSection());
194      sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get()));
195    } else if (SectionName == "producers") {
196      if (!IO.outputting())
197        Section.reset(new WasmYAML::ProducersSection());
198      sectionMapping(IO, *cast<WasmYAML::ProducersSection>(Section.get()));
199    } else if (SectionName == "target_features") {
200      if (!IO.outputting())
201        Section.reset(new WasmYAML::TargetFeaturesSection());
202      sectionMapping(IO, *cast<WasmYAML::TargetFeaturesSection>(Section.get()));
203    } else {
204      if (!IO.outputting())
205        Section.reset(new WasmYAML::CustomSection(SectionName));
206      sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get()));
207    }
208    break;
209  }
210  case wasm::WASM_SEC_TYPE:
211    if (!IO.outputting())
212      Section.reset(new WasmYAML::TypeSection());
213    sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get()));
214    break;
215  case wasm::WASM_SEC_IMPORT:
216    if (!IO.outputting())
217      Section.reset(new WasmYAML::ImportSection());
218    sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get()));
219    break;
220  case wasm::WASM_SEC_FUNCTION:
221    if (!IO.outputting())
222      Section.reset(new WasmYAML::FunctionSection());
223    sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get()));
224    break;
225  case wasm::WASM_SEC_TABLE:
226    if (!IO.outputting())
227      Section.reset(new WasmYAML::TableSection());
228    sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get()));
229    break;
230  case wasm::WASM_SEC_MEMORY:
231    if (!IO.outputting())
232      Section.reset(new WasmYAML::MemorySection());
233    sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get()));
234    break;
235  case wasm::WASM_SEC_TAG:
236    if (!IO.outputting())
237      Section.reset(new WasmYAML::TagSection());
238    sectionMapping(IO, *cast<WasmYAML::TagSection>(Section.get()));
239    break;
240  case wasm::WASM_SEC_GLOBAL:
241    if (!IO.outputting())
242      Section.reset(new WasmYAML::GlobalSection());
243    sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get()));
244    break;
245  case wasm::WASM_SEC_EXPORT:
246    if (!IO.outputting())
247      Section.reset(new WasmYAML::ExportSection());
248    sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get()));
249    break;
250  case wasm::WASM_SEC_START:
251    if (!IO.outputting())
252      Section.reset(new WasmYAML::StartSection());
253    sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get()));
254    break;
255  case wasm::WASM_SEC_ELEM:
256    if (!IO.outputting())
257      Section.reset(new WasmYAML::ElemSection());
258    sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get()));
259    break;
260  case wasm::WASM_SEC_CODE:
261    if (!IO.outputting())
262      Section.reset(new WasmYAML::CodeSection());
263    sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get()));
264    break;
265  case wasm::WASM_SEC_DATA:
266    if (!IO.outputting())
267      Section.reset(new WasmYAML::DataSection());
268    sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get()));
269    break;
270  case wasm::WASM_SEC_DATACOUNT:
271    if (!IO.outputting())
272      Section.reset(new WasmYAML::DataCountSection());
273    sectionMapping(IO, *cast<WasmYAML::DataCountSection>(Section.get()));
274    break;
275  default:
276    llvm_unreachable("Unknown section type");
277  }
278}
279
280void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration(
281    IO &IO, WasmYAML::SectionType &Type) {
282#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X);
283  ECase(CUSTOM);
284  ECase(TYPE);
285  ECase(IMPORT);
286  ECase(FUNCTION);
287  ECase(TABLE);
288  ECase(MEMORY);
289  ECase(GLOBAL);
290  ECase(TAG);
291  ECase(EXPORT);
292  ECase(START);
293  ECase(ELEM);
294  ECase(CODE);
295  ECase(DATA);
296  ECase(DATACOUNT);
297#undef ECase
298}
299
300void MappingTraits<WasmYAML::Signature>::mapping(
301    IO &IO, WasmYAML::Signature &Signature) {
302  IO.mapRequired("Index", Signature.Index);
303  IO.mapRequired("ParamTypes", Signature.ParamTypes);
304  IO.mapRequired("ReturnTypes", Signature.ReturnTypes);
305}
306
307void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) {
308  IO.mapRequired("Index", Table.Index);
309  IO.mapRequired("ElemType", Table.ElemType);
310  IO.mapRequired("Limits", Table.TableLimits);
311}
312
313void MappingTraits<WasmYAML::Function>::mapping(IO &IO,
314                                                WasmYAML::Function &Function) {
315  IO.mapRequired("Index", Function.Index);
316  IO.mapRequired("Locals", Function.Locals);
317  IO.mapRequired("Body", Function.Body);
318}
319
320void MappingTraits<WasmYAML::Relocation>::mapping(
321    IO &IO, WasmYAML::Relocation &Relocation) {
322  IO.mapRequired("Type", Relocation.Type);
323  IO.mapRequired("Index", Relocation.Index);
324  IO.mapRequired("Offset", Relocation.Offset);
325  IO.mapOptional("Addend", Relocation.Addend, 0);
326}
327
328void MappingTraits<WasmYAML::NameEntry>::mapping(
329    IO &IO, WasmYAML::NameEntry &NameEntry) {
330  IO.mapRequired("Index", NameEntry.Index);
331  IO.mapRequired("Name", NameEntry.Name);
332}
333
334void MappingTraits<WasmYAML::ProducerEntry>::mapping(
335    IO &IO, WasmYAML::ProducerEntry &ProducerEntry) {
336  IO.mapRequired("Name", ProducerEntry.Name);
337  IO.mapRequired("Version", ProducerEntry.Version);
338}
339
340void ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix>::enumeration(
341    IO &IO, WasmYAML::FeaturePolicyPrefix &Kind) {
342#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_FEATURE_PREFIX_##X);
343  ECase(USED);
344  ECase(REQUIRED);
345  ECase(DISALLOWED);
346#undef ECase
347}
348
349void MappingTraits<WasmYAML::FeatureEntry>::mapping(
350    IO &IO, WasmYAML::FeatureEntry &FeatureEntry) {
351  IO.mapRequired("Prefix", FeatureEntry.Prefix);
352  IO.mapRequired("Name", FeatureEntry.Name);
353}
354
355void MappingTraits<WasmYAML::SegmentInfo>::mapping(
356    IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
357  IO.mapRequired("Index", SegmentInfo.Index);
358  IO.mapRequired("Name", SegmentInfo.Name);
359  IO.mapRequired("Alignment", SegmentInfo.Alignment);
360  IO.mapRequired("Flags", SegmentInfo.Flags);
361}
362
363void MappingTraits<WasmYAML::LocalDecl>::mapping(
364    IO &IO, WasmYAML::LocalDecl &LocalDecl) {
365  IO.mapRequired("Type", LocalDecl.Type);
366  IO.mapRequired("Count", LocalDecl.Count);
367}
368
369void MappingTraits<WasmYAML::Limits>::mapping(IO &IO,
370                                              WasmYAML::Limits &Limits) {
371  IO.mapOptional("Flags", Limits.Flags, 0);
372  IO.mapRequired("Minimum", Limits.Minimum);
373  if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
374    IO.mapOptional("Maximum", Limits.Maximum);
375}
376
377void MappingTraits<WasmYAML::ElemSegment>::mapping(
378    IO &IO, WasmYAML::ElemSegment &Segment) {
379  IO.mapOptional("Flags", Segment.Flags, 0);
380  if (!IO.outputting() ||
381      Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER)
382    IO.mapOptional("TableNumber", Segment.TableNumber);
383  if (!IO.outputting() ||
384      Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND)
385    IO.mapOptional("ElemKind", Segment.ElemKind);
386  IO.mapRequired("Offset", Segment.Offset);
387  IO.mapRequired("Functions", Segment.Functions);
388}
389
390void MappingTraits<WasmYAML::Import>::mapping(IO &IO,
391                                              WasmYAML::Import &Import) {
392  IO.mapRequired("Module", Import.Module);
393  IO.mapRequired("Field", Import.Field);
394  IO.mapRequired("Kind", Import.Kind);
395  if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION ||
396      Import.Kind == wasm::WASM_EXTERNAL_TAG) {
397    IO.mapRequired("SigIndex", Import.SigIndex);
398  } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
399    IO.mapRequired("GlobalType", Import.GlobalImport.Type);
400    IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable);
401  } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) {
402    IO.mapRequired("Table", Import.TableImport);
403  } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY) {
404    IO.mapRequired("Memory", Import.Memory);
405  } else {
406    llvm_unreachable("unhandled import type");
407  }
408}
409
410void MappingTraits<WasmYAML::Export>::mapping(IO &IO,
411                                              WasmYAML::Export &Export) {
412  IO.mapRequired("Name", Export.Name);
413  IO.mapRequired("Kind", Export.Kind);
414  IO.mapRequired("Index", Export.Index);
415}
416
417void MappingTraits<WasmYAML::Global>::mapping(IO &IO,
418                                              WasmYAML::Global &Global) {
419  IO.mapRequired("Index", Global.Index);
420  IO.mapRequired("Type", Global.Type);
421  IO.mapRequired("Mutable", Global.Mutable);
422  IO.mapRequired("InitExpr", Global.Init);
423}
424
425void MappingTraits<WasmYAML::InitExpr>::mapping(IO &IO,
426                                                WasmYAML::InitExpr &Expr) {
427  IO.mapOptional("Extended", Expr.Extended, false);
428  if (Expr.Extended) {
429    IO.mapRequired("Body", Expr.Body);
430  } else {
431    WasmYAML::Opcode Op = Expr.Inst.Opcode;
432    IO.mapRequired("Opcode", Op);
433    Expr.Inst.Opcode = Op;
434    switch (Expr.Inst.Opcode) {
435    case wasm::WASM_OPCODE_I32_CONST:
436      IO.mapRequired("Value", Expr.Inst.Value.Int32);
437      break;
438    case wasm::WASM_OPCODE_I64_CONST:
439      IO.mapRequired("Value", Expr.Inst.Value.Int64);
440      break;
441    case wasm::WASM_OPCODE_F32_CONST:
442      IO.mapRequired("Value", Expr.Inst.Value.Float32);
443      break;
444    case wasm::WASM_OPCODE_F64_CONST:
445      IO.mapRequired("Value", Expr.Inst.Value.Float64);
446      break;
447    case wasm::WASM_OPCODE_GLOBAL_GET:
448      IO.mapRequired("Index", Expr.Inst.Value.Global);
449      break;
450    case wasm::WASM_OPCODE_REF_NULL: {
451      WasmYAML::ValueType Ty = wasm::WASM_TYPE_EXTERNREF;
452      IO.mapRequired("Type", Ty);
453      break;
454    }
455    }
456  }
457}
458
459void MappingTraits<WasmYAML::DataSegment>::mapping(
460    IO &IO, WasmYAML::DataSegment &Segment) {
461  IO.mapOptional("SectionOffset", Segment.SectionOffset);
462  IO.mapRequired("InitFlags", Segment.InitFlags);
463  if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) {
464    IO.mapRequired("MemoryIndex", Segment.MemoryIndex);
465  } else {
466    Segment.MemoryIndex = 0;
467  }
468  if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
469    IO.mapRequired("Offset", Segment.Offset);
470  } else {
471    Segment.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST;
472    Segment.Offset.Inst.Value.Int32 = 0;
473  }
474  IO.mapRequired("Content", Segment.Content);
475}
476
477void MappingTraits<WasmYAML::InitFunction>::mapping(
478    IO &IO, WasmYAML::InitFunction &Init) {
479  IO.mapRequired("Priority", Init.Priority);
480  IO.mapRequired("Symbol", Init.Symbol);
481}
482
483void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
484    IO &IO, WasmYAML::ComdatKind &Kind) {
485#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
486  ECase(FUNCTION);
487  ECase(DATA);
488  ECase(SECTION);
489#undef ECase
490}
491
492void MappingTraits<WasmYAML::ComdatEntry>::mapping(
493    IO &IO, WasmYAML::ComdatEntry &ComdatEntry) {
494  IO.mapRequired("Kind", ComdatEntry.Kind);
495  IO.mapRequired("Index", ComdatEntry.Index);
496}
497
498void MappingTraits<WasmYAML::Comdat>::mapping(IO &IO,
499                                              WasmYAML::Comdat &Comdat) {
500  IO.mapRequired("Name", Comdat.Name);
501  IO.mapRequired("Entries", Comdat.Entries);
502}
503
504void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
505                                                  WasmYAML::SymbolInfo &Info) {
506  IO.mapRequired("Index", Info.Index);
507  IO.mapRequired("Kind", Info.Kind);
508  if (Info.Kind != wasm::WASM_SYMBOL_TYPE_SECTION)
509    IO.mapRequired("Name", Info.Name);
510  IO.mapRequired("Flags", Info.Flags);
511  if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
512    IO.mapRequired("Function", Info.ElementIndex);
513  } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
514    IO.mapRequired("Global", Info.ElementIndex);
515  } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE) {
516    IO.mapRequired("Table", Info.ElementIndex);
517  } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TAG) {
518    IO.mapRequired("Tag", Info.ElementIndex);
519  } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
520    if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
521      if ((Info.Flags & wasm::WASM_SYMBOL_ABSOLUTE) == 0) {
522        IO.mapRequired("Segment", Info.DataRef.Segment);
523      }
524      IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
525      IO.mapRequired("Size", Info.DataRef.Size);
526    }
527  } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) {
528    IO.mapRequired("Section", Info.ElementIndex);
529  } else {
530    llvm_unreachable("unsupported symbol kind");
531  }
532}
533
534void MappingTraits<WasmYAML::DylinkImportInfo>::mapping(
535    IO &IO, WasmYAML::DylinkImportInfo &Info) {
536  IO.mapRequired("Module", Info.Module);
537  IO.mapRequired("Field", Info.Field);
538  IO.mapRequired("Flags", Info.Flags);
539}
540
541void MappingTraits<WasmYAML::DylinkExportInfo>::mapping(
542    IO &IO, WasmYAML::DylinkExportInfo &Info) {
543  IO.mapRequired("Name", Info.Name);
544  IO.mapRequired("Flags", Info.Flags);
545}
546
547void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
548    IO &IO, WasmYAML::LimitFlags &Value) {
549#define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X)
550  BCase(HAS_MAX);
551  BCase(IS_SHARED);
552  BCase(IS_64);
553#undef BCase
554}
555
556void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset(
557    IO &IO, WasmYAML::SegmentFlags &Value) {
558#define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_SEG_FLAG_##X)
559  BCase(STRINGS);
560  BCase(TLS);
561#undef BCase
562}
563
564void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset(
565    IO &IO, WasmYAML::SymbolFlags &Value) {
566#define BCaseMask(M, X)                                                        \
567  IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M)
568  // BCaseMask(BINDING_MASK, BINDING_GLOBAL);
569  BCaseMask(BINDING_MASK, BINDING_WEAK);
570  BCaseMask(BINDING_MASK, BINDING_LOCAL);
571  // BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
572  BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
573  BCaseMask(UNDEFINED, UNDEFINED);
574  BCaseMask(EXPORTED, EXPORTED);
575  BCaseMask(EXPLICIT_NAME, EXPLICIT_NAME);
576  BCaseMask(NO_STRIP, NO_STRIP);
577  BCaseMask(TLS, TLS);
578  BCaseMask(ABSOLUTE, ABSOLUTE);
579#undef BCaseMask
580}
581
582void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
583    IO &IO, WasmYAML::SymbolKind &Kind) {
584#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
585  ECase(FUNCTION);
586  ECase(DATA);
587  ECase(GLOBAL);
588  ECase(TABLE);
589  ECase(SECTION);
590  ECase(TAG);
591#undef ECase
592}
593
594void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
595    IO &IO, WasmYAML::ValueType &Type) {
596#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
597  ECase(I32);
598  ECase(I64);
599  ECase(F32);
600  ECase(F64);
601  ECase(V128);
602  ECase(FUNCREF);
603  ECase(EXTERNREF);
604  ECase(FUNC);
605#undef ECase
606}
607
608void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration(
609    IO &IO, WasmYAML::ExportKind &Kind) {
610#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X);
611  ECase(FUNCTION);
612  ECase(TABLE);
613  ECase(MEMORY);
614  ECase(GLOBAL);
615  ECase(TAG);
616#undef ECase
617}
618
619void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration(
620    IO &IO, WasmYAML::Opcode &Code) {
621#define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X);
622  ECase(END);
623  ECase(I32_CONST);
624  ECase(I64_CONST);
625  ECase(F64_CONST);
626  ECase(F32_CONST);
627  ECase(GLOBAL_GET);
628  ECase(REF_NULL);
629#undef ECase
630}
631
632void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration(
633    IO &IO, WasmYAML::TableType &Type) {
634#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
635  ECase(FUNCREF);
636  ECase(EXTERNREF);
637#undef ECase
638}
639
640void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration(
641    IO &IO, WasmYAML::RelocType &Type) {
642#define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name);
643#include "llvm/BinaryFormat/WasmRelocs.def"
644#undef WASM_RELOC
645  IO.enumFallback<Hex32>(Type);
646}
647
648} // end namespace yaml
649
650} // end namespace llvm
651