Bug Summary

File:llvm/include/llvm/Support/YAMLTraits.h
Warning:line 812, column 17
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ELFYAML.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/lib/ObjectYAML -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-01-13-084841-49055-1 -x c++ /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp

1//===- ELFYAML.cpp - ELF 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 ELF.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ObjectYAML/ELFYAML.h"
14#include "llvm/ADT/MapVector.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/BinaryFormat/ELF.h"
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/ErrorHandling.h"
19#include "llvm/Support/MipsABIFlags.h"
20#include "llvm/Support/YAMLTraits.h"
21#include "llvm/Support/WithColor.h"
22#include <cassert>
23#include <cstdint>
24
25namespace llvm {
26
27ELFYAML::Chunk::~Chunk() = default;
28
29namespace yaml {
30
31void ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(
32 IO &IO, ELFYAML::ELF_ET &Value) {
33#define ECase(X) IO.enumCase(Value, #X, ELF::X)
34 ECase(ET_NONE);
35 ECase(ET_REL);
36 ECase(ET_EXEC);
37 ECase(ET_DYN);
38 ECase(ET_CORE);
39#undef ECase
40 IO.enumFallback<Hex16>(Value);
41}
42
43void ScalarEnumerationTraits<ELFYAML::ELF_PT>::enumeration(
44 IO &IO, ELFYAML::ELF_PT &Value) {
45#define ECase(X) IO.enumCase(Value, #X, ELF::X)
46 ECase(PT_NULL);
47 ECase(PT_LOAD);
48 ECase(PT_DYNAMIC);
49 ECase(PT_INTERP);
50 ECase(PT_NOTE);
51 ECase(PT_SHLIB);
52 ECase(PT_PHDR);
53 ECase(PT_TLS);
54 ECase(PT_GNU_EH_FRAME);
55 ECase(PT_GNU_STACK);
56 ECase(PT_GNU_RELRO);
57 ECase(PT_GNU_PROPERTY);
58#undef ECase
59 IO.enumFallback<Hex32>(Value);
60}
61
62void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(
63 IO &IO, ELFYAML::ELF_EM &Value) {
64#define ECase(X) IO.enumCase(Value, #X, ELF::X)
65 ECase(EM_NONE);
66 ECase(EM_M32);
67 ECase(EM_SPARC);
68 ECase(EM_386);
69 ECase(EM_68K);
70 ECase(EM_88K);
71 ECase(EM_IAMCU);
72 ECase(EM_860);
73 ECase(EM_MIPS);
74 ECase(EM_S370);
75 ECase(EM_MIPS_RS3_LE);
76 ECase(EM_PARISC);
77 ECase(EM_VPP500);
78 ECase(EM_SPARC32PLUS);
79 ECase(EM_960);
80 ECase(EM_PPC);
81 ECase(EM_PPC64);
82 ECase(EM_S390);
83 ECase(EM_SPU);
84 ECase(EM_V800);
85 ECase(EM_FR20);
86 ECase(EM_RH32);
87 ECase(EM_RCE);
88 ECase(EM_ARM);
89 ECase(EM_ALPHA);
90 ECase(EM_SH);
91 ECase(EM_SPARCV9);
92 ECase(EM_TRICORE);
93 ECase(EM_ARC);
94 ECase(EM_H8_300);
95 ECase(EM_H8_300H);
96 ECase(EM_H8S);
97 ECase(EM_H8_500);
98 ECase(EM_IA_64);
99 ECase(EM_MIPS_X);
100 ECase(EM_COLDFIRE);
101 ECase(EM_68HC12);
102 ECase(EM_MMA);
103 ECase(EM_PCP);
104 ECase(EM_NCPU);
105 ECase(EM_NDR1);
106 ECase(EM_STARCORE);
107 ECase(EM_ME16);
108 ECase(EM_ST100);
109 ECase(EM_TINYJ);
110 ECase(EM_X86_64);
111 ECase(EM_PDSP);
112 ECase(EM_PDP10);
113 ECase(EM_PDP11);
114 ECase(EM_FX66);
115 ECase(EM_ST9PLUS);
116 ECase(EM_ST7);
117 ECase(EM_68HC16);
118 ECase(EM_68HC11);
119 ECase(EM_68HC08);
120 ECase(EM_68HC05);
121 ECase(EM_SVX);
122 ECase(EM_ST19);
123 ECase(EM_VAX);
124 ECase(EM_CRIS);
125 ECase(EM_JAVELIN);
126 ECase(EM_FIREPATH);
127 ECase(EM_ZSP);
128 ECase(EM_MMIX);
129 ECase(EM_HUANY);
130 ECase(EM_PRISM);
131 ECase(EM_AVR);
132 ECase(EM_FR30);
133 ECase(EM_D10V);
134 ECase(EM_D30V);
135 ECase(EM_V850);
136 ECase(EM_M32R);
137 ECase(EM_MN10300);
138 ECase(EM_MN10200);
139 ECase(EM_PJ);
140 ECase(EM_OPENRISC);
141 ECase(EM_ARC_COMPACT);
142 ECase(EM_XTENSA);
143 ECase(EM_VIDEOCORE);
144 ECase(EM_TMM_GPP);
145 ECase(EM_NS32K);
146 ECase(EM_TPC);
147 ECase(EM_SNP1K);
148 ECase(EM_ST200);
149 ECase(EM_IP2K);
150 ECase(EM_MAX);
151 ECase(EM_CR);
152 ECase(EM_F2MC16);
153 ECase(EM_MSP430);
154 ECase(EM_BLACKFIN);
155 ECase(EM_SE_C33);
156 ECase(EM_SEP);
157 ECase(EM_ARCA);
158 ECase(EM_UNICORE);
159 ECase(EM_EXCESS);
160 ECase(EM_DXP);
161 ECase(EM_ALTERA_NIOS2);
162 ECase(EM_CRX);
163 ECase(EM_XGATE);
164 ECase(EM_C166);
165 ECase(EM_M16C);
166 ECase(EM_DSPIC30F);
167 ECase(EM_CE);
168 ECase(EM_M32C);
169 ECase(EM_TSK3000);
170 ECase(EM_RS08);
171 ECase(EM_SHARC);
172 ECase(EM_ECOG2);
173 ECase(EM_SCORE7);
174 ECase(EM_DSP24);
175 ECase(EM_VIDEOCORE3);
176 ECase(EM_LATTICEMICO32);
177 ECase(EM_SE_C17);
178 ECase(EM_TI_C6000);
179 ECase(EM_TI_C2000);
180 ECase(EM_TI_C5500);
181 ECase(EM_MMDSP_PLUS);
182 ECase(EM_CYPRESS_M8C);
183 ECase(EM_R32C);
184 ECase(EM_TRIMEDIA);
185 ECase(EM_HEXAGON);
186 ECase(EM_8051);
187 ECase(EM_STXP7X);
188 ECase(EM_NDS32);
189 ECase(EM_ECOG1);
190 ECase(EM_ECOG1X);
191 ECase(EM_MAXQ30);
192 ECase(EM_XIMO16);
193 ECase(EM_MANIK);
194 ECase(EM_CRAYNV2);
195 ECase(EM_RX);
196 ECase(EM_METAG);
197 ECase(EM_MCST_ELBRUS);
198 ECase(EM_ECOG16);
199 ECase(EM_CR16);
200 ECase(EM_ETPU);
201 ECase(EM_SLE9X);
202 ECase(EM_L10M);
203 ECase(EM_K10M);
204 ECase(EM_AARCH64);
205 ECase(EM_AVR32);
206 ECase(EM_STM8);
207 ECase(EM_TILE64);
208 ECase(EM_TILEPRO);
209 ECase(EM_CUDA);
210 ECase(EM_TILEGX);
211 ECase(EM_CLOUDSHIELD);
212 ECase(EM_COREA_1ST);
213 ECase(EM_COREA_2ND);
214 ECase(EM_ARC_COMPACT2);
215 ECase(EM_OPEN8);
216 ECase(EM_RL78);
217 ECase(EM_VIDEOCORE5);
218 ECase(EM_78KOR);
219 ECase(EM_56800EX);
220 ECase(EM_AMDGPU);
221 ECase(EM_RISCV);
222 ECase(EM_LANAI);
223 ECase(EM_BPF);
224#undef ECase
225 IO.enumFallback<Hex16>(Value);
226}
227
228void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
229 IO &IO, ELFYAML::ELF_ELFCLASS &Value) {
230#define ECase(X) IO.enumCase(Value, #X, ELF::X)
231 // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it
232 // here.
233 ECase(ELFCLASS32);
234 ECase(ELFCLASS64);
235#undef ECase
236}
237
238void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
239 IO &IO, ELFYAML::ELF_ELFDATA &Value) {
240#define ECase(X) IO.enumCase(Value, #X, ELF::X)
241 // ELFDATANONE is an invalid data encoding, but we accept it because
242 // we want to be able to produce invalid binaries for the tests.
243 ECase(ELFDATANONE);
244 ECase(ELFDATA2LSB);
245 ECase(ELFDATA2MSB);
246#undef ECase
247}
248
249void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
250 IO &IO, ELFYAML::ELF_ELFOSABI &Value) {
251#define ECase(X) IO.enumCase(Value, #X, ELF::X)
252 ECase(ELFOSABI_NONE);
253 ECase(ELFOSABI_HPUX);
254 ECase(ELFOSABI_NETBSD);
255 ECase(ELFOSABI_GNU);
256 ECase(ELFOSABI_LINUX);
257 ECase(ELFOSABI_HURD);
258 ECase(ELFOSABI_SOLARIS);
259 ECase(ELFOSABI_AIX);
260 ECase(ELFOSABI_IRIX);
261 ECase(ELFOSABI_FREEBSD);
262 ECase(ELFOSABI_TRU64);
263 ECase(ELFOSABI_MODESTO);
264 ECase(ELFOSABI_OPENBSD);
265 ECase(ELFOSABI_OPENVMS);
266 ECase(ELFOSABI_NSK);
267 ECase(ELFOSABI_AROS);
268 ECase(ELFOSABI_FENIXOS);
269 ECase(ELFOSABI_CLOUDABI);
270 ECase(ELFOSABI_AMDGPU_HSA);
271 ECase(ELFOSABI_AMDGPU_PAL);
272 ECase(ELFOSABI_AMDGPU_MESA3D);
273 ECase(ELFOSABI_ARM);
274 ECase(ELFOSABI_C6000_ELFABI);
275 ECase(ELFOSABI_C6000_LINUX);
276 ECase(ELFOSABI_STANDALONE);
277#undef ECase
278 IO.enumFallback<Hex8>(Value);
279}
280
281void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
282 ELFYAML::ELF_EF &Value) {
283 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
284 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 284, __PRETTY_FUNCTION__))
;
285#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
286#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M)
287 switch (Object->Header.Machine) {
288 case ELF::EM_ARM:
289 BCase(EF_ARM_SOFT_FLOAT);
290 BCase(EF_ARM_VFP_FLOAT);
291 BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK);
292 BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK);
293 BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK);
294 BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK);
295 BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK);
296 BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK);
297 break;
298 case ELF::EM_MIPS:
299 BCase(EF_MIPS_NOREORDER);
300 BCase(EF_MIPS_PIC);
301 BCase(EF_MIPS_CPIC);
302 BCase(EF_MIPS_ABI2);
303 BCase(EF_MIPS_32BITMODE);
304 BCase(EF_MIPS_FP64);
305 BCase(EF_MIPS_NAN2008);
306 BCase(EF_MIPS_MICROMIPS);
307 BCase(EF_MIPS_ARCH_ASE_M16);
308 BCase(EF_MIPS_ARCH_ASE_MDMX);
309 BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI);
310 BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI);
311 BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI);
312 BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI);
313 BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH);
314 BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH);
315 BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH);
316 BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH);
317 BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH);
318 BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH);
319 BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH);
320 BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH);
321 BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH);
322 BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH);
323 BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH);
324 BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH);
325 BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH);
326 BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH);
327 BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH);
328 BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH);
329 BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH);
330 BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH);
331 BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH);
332 BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH);
333 BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH);
334 BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH);
335 BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH);
336 BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH);
337 BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH);
338 BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH);
339 BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH);
340 BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH);
341 BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH);
342 break;
343 case ELF::EM_HEXAGON:
344 BCase(EF_HEXAGON_MACH_V2);
345 BCase(EF_HEXAGON_MACH_V3);
346 BCase(EF_HEXAGON_MACH_V4);
347 BCase(EF_HEXAGON_MACH_V5);
348 BCase(EF_HEXAGON_MACH_V55);
349 BCase(EF_HEXAGON_MACH_V60);
350 BCase(EF_HEXAGON_MACH_V62);
351 BCase(EF_HEXAGON_MACH_V65);
352 BCase(EF_HEXAGON_ISA_V2);
353 BCase(EF_HEXAGON_ISA_V3);
354 BCase(EF_HEXAGON_ISA_V4);
355 BCase(EF_HEXAGON_ISA_V5);
356 BCase(EF_HEXAGON_ISA_V55);
357 BCase(EF_HEXAGON_ISA_V60);
358 BCase(EF_HEXAGON_ISA_V62);
359 BCase(EF_HEXAGON_ISA_V65);
360 break;
361 case ELF::EM_AVR:
362 BCase(EF_AVR_ARCH_AVR1);
363 BCase(EF_AVR_ARCH_AVR2);
364 BCase(EF_AVR_ARCH_AVR25);
365 BCase(EF_AVR_ARCH_AVR3);
366 BCase(EF_AVR_ARCH_AVR31);
367 BCase(EF_AVR_ARCH_AVR35);
368 BCase(EF_AVR_ARCH_AVR4);
369 BCase(EF_AVR_ARCH_AVR51);
370 BCase(EF_AVR_ARCH_AVR6);
371 BCase(EF_AVR_ARCH_AVRTINY);
372 BCase(EF_AVR_ARCH_XMEGA1);
373 BCase(EF_AVR_ARCH_XMEGA2);
374 BCase(EF_AVR_ARCH_XMEGA3);
375 BCase(EF_AVR_ARCH_XMEGA4);
376 BCase(EF_AVR_ARCH_XMEGA5);
377 BCase(EF_AVR_ARCH_XMEGA6);
378 BCase(EF_AVR_ARCH_XMEGA7);
379 break;
380 case ELF::EM_RISCV:
381 BCase(EF_RISCV_RVC);
382 BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);
383 BCaseMask(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI);
384 BCaseMask(EF_RISCV_FLOAT_ABI_DOUBLE, EF_RISCV_FLOAT_ABI);
385 BCaseMask(EF_RISCV_FLOAT_ABI_QUAD, EF_RISCV_FLOAT_ABI);
386 BCase(EF_RISCV_RVE);
387 break;
388 case ELF::EM_AMDGPU:
389 BCaseMask(EF_AMDGPU_MACH_NONE, EF_AMDGPU_MACH);
390 BCaseMask(EF_AMDGPU_MACH_R600_R600, EF_AMDGPU_MACH);
391 BCaseMask(EF_AMDGPU_MACH_R600_R630, EF_AMDGPU_MACH);
392 BCaseMask(EF_AMDGPU_MACH_R600_RS880, EF_AMDGPU_MACH);
393 BCaseMask(EF_AMDGPU_MACH_R600_RV670, EF_AMDGPU_MACH);
394 BCaseMask(EF_AMDGPU_MACH_R600_RV710, EF_AMDGPU_MACH);
395 BCaseMask(EF_AMDGPU_MACH_R600_RV730, EF_AMDGPU_MACH);
396 BCaseMask(EF_AMDGPU_MACH_R600_RV770, EF_AMDGPU_MACH);
397 BCaseMask(EF_AMDGPU_MACH_R600_CEDAR, EF_AMDGPU_MACH);
398 BCaseMask(EF_AMDGPU_MACH_R600_CYPRESS, EF_AMDGPU_MACH);
399 BCaseMask(EF_AMDGPU_MACH_R600_JUNIPER, EF_AMDGPU_MACH);
400 BCaseMask(EF_AMDGPU_MACH_R600_REDWOOD, EF_AMDGPU_MACH);
401 BCaseMask(EF_AMDGPU_MACH_R600_SUMO, EF_AMDGPU_MACH);
402 BCaseMask(EF_AMDGPU_MACH_R600_BARTS, EF_AMDGPU_MACH);
403 BCaseMask(EF_AMDGPU_MACH_R600_CAICOS, EF_AMDGPU_MACH);
404 BCaseMask(EF_AMDGPU_MACH_R600_CAYMAN, EF_AMDGPU_MACH);
405 BCaseMask(EF_AMDGPU_MACH_R600_TURKS, EF_AMDGPU_MACH);
406 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX600, EF_AMDGPU_MACH);
407 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX601, EF_AMDGPU_MACH);
408 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX700, EF_AMDGPU_MACH);
409 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX701, EF_AMDGPU_MACH);
410 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX702, EF_AMDGPU_MACH);
411 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX703, EF_AMDGPU_MACH);
412 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX704, EF_AMDGPU_MACH);
413 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX801, EF_AMDGPU_MACH);
414 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX802, EF_AMDGPU_MACH);
415 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX803, EF_AMDGPU_MACH);
416 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX810, EF_AMDGPU_MACH);
417 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX900, EF_AMDGPU_MACH);
418 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX902, EF_AMDGPU_MACH);
419 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX904, EF_AMDGPU_MACH);
420 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX906, EF_AMDGPU_MACH);
421 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX908, EF_AMDGPU_MACH);
422 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX909, EF_AMDGPU_MACH);
423 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH);
424 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH);
425 BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH);
426 BCase(EF_AMDGPU_XNACK);
427 BCase(EF_AMDGPU_SRAM_ECC);
428 break;
429 case ELF::EM_X86_64:
430 break;
431 default:
432 llvm_unreachable("Unsupported architecture")::llvm::llvm_unreachable_internal("Unsupported architecture",
"/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 432)
;
433 }
434#undef BCase
435#undef BCaseMask
436}
437
438void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
439 IO &IO, ELFYAML::ELF_SHT &Value) {
440 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
441 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 441, __PRETTY_FUNCTION__))
;
14
Assuming 'Object' is non-null
15
'?' condition is true
442#define ECase(X) IO.enumCase(Value, #X, ELF::X)
443 ECase(SHT_NULL);
16
Calling 'IO::enumCase'
21
Returning from 'IO::enumCase'
444 ECase(SHT_PROGBITS);
22
Calling 'IO::enumCase'
27
Returning from 'IO::enumCase'
445 ECase(SHT_SYMTAB);
28
Calling 'IO::enumCase'
33
Returning from 'IO::enumCase'
446 // FIXME: Issue a diagnostic with this information.
447 ECase(SHT_STRTAB);
34
Calling 'IO::enumCase'
39
Returning from 'IO::enumCase'
448 ECase(SHT_RELA);
40
Calling 'IO::enumCase'
45
Returning from 'IO::enumCase'
449 ECase(SHT_HASH);
46
Calling 'IO::enumCase'
51
Returning from 'IO::enumCase'
450 ECase(SHT_DYNAMIC);
52
Calling 'IO::enumCase'
57
Returning from 'IO::enumCase'
451 ECase(SHT_NOTE);
58
Calling 'IO::enumCase'
63
Returning from 'IO::enumCase'
452 ECase(SHT_NOBITS);
64
Calling 'IO::enumCase'
69
Returning from 'IO::enumCase'
453 ECase(SHT_REL);
70
Calling 'IO::enumCase'
75
Returning from 'IO::enumCase'
454 ECase(SHT_SHLIB);
76
Calling 'IO::enumCase'
81
Returning from 'IO::enumCase'
455 ECase(SHT_DYNSYM);
82
Calling 'IO::enumCase'
87
Returning from 'IO::enumCase'
456 ECase(SHT_INIT_ARRAY);
88
Calling 'IO::enumCase'
93
Returning from 'IO::enumCase'
457 ECase(SHT_FINI_ARRAY);
94
Calling 'IO::enumCase'
99
Returning from 'IO::enumCase'
458 ECase(SHT_PREINIT_ARRAY);
100
Calling 'IO::enumCase'
105
Returning from 'IO::enumCase'
459 ECase(SHT_GROUP);
106
Calling 'IO::enumCase'
111
Returning from 'IO::enumCase'
460 ECase(SHT_SYMTAB_SHNDX);
112
Calling 'IO::enumCase'
117
Returning from 'IO::enumCase'
461 ECase(SHT_RELR);
118
Calling 'IO::enumCase'
123
Returning from 'IO::enumCase'
462 ECase(SHT_ANDROID_REL);
124
Calling 'IO::enumCase'
129
Returning from 'IO::enumCase'
463 ECase(SHT_ANDROID_RELA);
130
Calling 'IO::enumCase'
135
Returning from 'IO::enumCase'
464 ECase(SHT_ANDROID_RELR);
136
Calling 'IO::enumCase'
141
Returning from 'IO::enumCase'
465 ECase(SHT_LLVM_ODRTAB);
142
Calling 'IO::enumCase'
147
Returning from 'IO::enumCase'
466 ECase(SHT_LLVM_LINKER_OPTIONS);
148
Calling 'IO::enumCase'
153
Returning from 'IO::enumCase'
467 ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
154
Calling 'IO::enumCase'
159
Returning from 'IO::enumCase'
468 ECase(SHT_LLVM_ADDRSIG);
160
Calling 'IO::enumCase'
165
Returning from 'IO::enumCase'
469 ECase(SHT_LLVM_DEPENDENT_LIBRARIES);
166
Calling 'IO::enumCase'
171
Returning from 'IO::enumCase'
470 ECase(SHT_LLVM_SYMPART);
172
Calling 'IO::enumCase'
177
Returning from 'IO::enumCase'
471 ECase(SHT_LLVM_PART_EHDR);
178
Calling 'IO::enumCase'
183
Returning from 'IO::enumCase'
472 ECase(SHT_LLVM_PART_PHDR);
184
Calling 'IO::enumCase'
189
Returning from 'IO::enumCase'
473 ECase(SHT_GNU_ATTRIBUTES);
190
Calling 'IO::enumCase'
195
Returning from 'IO::enumCase'
474 ECase(SHT_GNU_HASH);
196
Calling 'IO::enumCase'
201
Returning from 'IO::enumCase'
475 ECase(SHT_GNU_verdef);
202
Calling 'IO::enumCase'
207
Returning from 'IO::enumCase'
476 ECase(SHT_GNU_verneed);
208
Calling 'IO::enumCase'
213
Returning from 'IO::enumCase'
477 ECase(SHT_GNU_versym);
214
Calling 'IO::enumCase'
219
Returning from 'IO::enumCase'
478 switch (Object->Header.Machine) {
220
Control jumps to the 'default' case at line 498
479 case ELF::EM_ARM:
480 ECase(SHT_ARM_EXIDX);
481 ECase(SHT_ARM_PREEMPTMAP);
482 ECase(SHT_ARM_ATTRIBUTES);
483 ECase(SHT_ARM_DEBUGOVERLAY);
484 ECase(SHT_ARM_OVERLAYSECTION);
485 break;
486 case ELF::EM_HEXAGON:
487 ECase(SHT_HEX_ORDERED);
488 break;
489 case ELF::EM_X86_64:
490 ECase(SHT_X86_64_UNWIND);
491 break;
492 case ELF::EM_MIPS:
493 ECase(SHT_MIPS_REGINFO);
494 ECase(SHT_MIPS_OPTIONS);
495 ECase(SHT_MIPS_DWARF);
496 ECase(SHT_MIPS_ABIFLAGS);
497 break;
498 default:
499 // Nothing to do.
500 break;
221
Execution continues on line 503
501 }
502#undef ECase
503 IO.enumFallback<Hex32>(Value);
222
Calling 'IO::enumFallback'
504}
505
506void ScalarBitSetTraits<ELFYAML::ELF_PF>::bitset(IO &IO,
507 ELFYAML::ELF_PF &Value) {
508#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
509 BCase(PF_X);
510 BCase(PF_W);
511 BCase(PF_R);
512}
513
514void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
515 ELFYAML::ELF_SHF &Value) {
516 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
517#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
518 BCase(SHF_WRITE);
519 BCase(SHF_ALLOC);
520 BCase(SHF_EXCLUDE);
521 BCase(SHF_EXECINSTR);
522 BCase(SHF_MERGE);
523 BCase(SHF_STRINGS);
524 BCase(SHF_INFO_LINK);
525 BCase(SHF_LINK_ORDER);
526 BCase(SHF_OS_NONCONFORMING);
527 BCase(SHF_GROUP);
528 BCase(SHF_TLS);
529 BCase(SHF_COMPRESSED);
530 switch (Object->Header.Machine) {
531 case ELF::EM_ARM:
532 BCase(SHF_ARM_PURECODE);
533 break;
534 case ELF::EM_HEXAGON:
535 BCase(SHF_HEX_GPREL);
536 break;
537 case ELF::EM_MIPS:
538 BCase(SHF_MIPS_NODUPES);
539 BCase(SHF_MIPS_NAMES);
540 BCase(SHF_MIPS_LOCAL);
541 BCase(SHF_MIPS_NOSTRIP);
542 BCase(SHF_MIPS_GPREL);
543 BCase(SHF_MIPS_MERGE);
544 BCase(SHF_MIPS_ADDR);
545 BCase(SHF_MIPS_STRING);
546 break;
547 case ELF::EM_X86_64:
548 BCase(SHF_X86_64_LARGE);
549 break;
550 default:
551 // Nothing to do.
552 break;
553 }
554#undef BCase
555}
556
557void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
558 IO &IO, ELFYAML::ELF_SHN &Value) {
559#define ECase(X) IO.enumCase(Value, #X, ELF::X)
560 ECase(SHN_UNDEF);
561 ECase(SHN_LORESERVE);
562 ECase(SHN_LOPROC);
563 ECase(SHN_HIPROC);
564 ECase(SHN_LOOS);
565 ECase(SHN_HIOS);
566 ECase(SHN_ABS);
567 ECase(SHN_COMMON);
568 ECase(SHN_XINDEX);
569 ECase(SHN_HIRESERVE);
570 ECase(SHN_AMDGPU_LDS);
571 ECase(SHN_HEXAGON_SCOMMON);
572 ECase(SHN_HEXAGON_SCOMMON_1);
573 ECase(SHN_HEXAGON_SCOMMON_2);
574 ECase(SHN_HEXAGON_SCOMMON_4);
575 ECase(SHN_HEXAGON_SCOMMON_8);
576#undef ECase
577 IO.enumFallback<Hex16>(Value);
578}
579
580void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
581 IO &IO, ELFYAML::ELF_STB &Value) {
582#define ECase(X) IO.enumCase(Value, #X, ELF::X)
583 ECase(STB_LOCAL);
584 ECase(STB_GLOBAL);
585 ECase(STB_WEAK);
586 ECase(STB_GNU_UNIQUE);
587#undef ECase
588 IO.enumFallback<Hex8>(Value);
589}
590
591void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
592 IO &IO, ELFYAML::ELF_STT &Value) {
593#define ECase(X) IO.enumCase(Value, #X, ELF::X)
594 ECase(STT_NOTYPE);
595 ECase(STT_OBJECT);
596 ECase(STT_FUNC);
597 ECase(STT_SECTION);
598 ECase(STT_FILE);
599 ECase(STT_COMMON);
600 ECase(STT_TLS);
601 ECase(STT_GNU_IFUNC);
602#undef ECase
603 IO.enumFallback<Hex8>(Value);
604}
605
606
607void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
608 IO &IO, ELFYAML::ELF_RSS &Value) {
609#define ECase(X) IO.enumCase(Value, #X, ELF::X)
610 ECase(RSS_UNDEF);
611 ECase(RSS_GP);
612 ECase(RSS_GP0);
613 ECase(RSS_LOC);
614#undef ECase
615}
616
617void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
618 IO &IO, ELFYAML::ELF_REL &Value) {
619 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
620 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 620, __PRETTY_FUNCTION__))
;
621#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
622 switch (Object->Header.Machine) {
623 case ELF::EM_X86_64:
624#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
625 break;
626 case ELF::EM_MIPS:
627#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
628 break;
629 case ELF::EM_HEXAGON:
630#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
631 break;
632 case ELF::EM_386:
633 case ELF::EM_IAMCU:
634#include "llvm/BinaryFormat/ELFRelocs/i386.def"
635 break;
636 case ELF::EM_AARCH64:
637#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
638 break;
639 case ELF::EM_ARM:
640#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
641 break;
642 case ELF::EM_ARC:
643#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
644 break;
645 case ELF::EM_RISCV:
646#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
647 break;
648 case ELF::EM_LANAI:
649#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
650 break;
651 case ELF::EM_AMDGPU:
652#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
653 break;
654 case ELF::EM_BPF:
655#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
656 break;
657 case ELF::EM_PPC64:
658#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
659 break;
660 default:
661 // Nothing to do.
662 break;
663 }
664#undef ELF_RELOC
665 IO.enumFallback<Hex32>(Value);
666}
667
668void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
669 IO &IO, ELFYAML::ELF_DYNTAG &Value) {
670 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
671 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 671, __PRETTY_FUNCTION__))
;
672
673// Disable architecture specific tags by default. We might enable them below.
674#define AARCH64_DYNAMIC_TAG(name, value)
675#define MIPS_DYNAMIC_TAG(name, value)
676#define HEXAGON_DYNAMIC_TAG(name, value)
677#define PPC_DYNAMIC_TAG(name, value)
678#define PPC64_DYNAMIC_TAG(name, value)
679// Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
680#define DYNAMIC_TAG_MARKER(name, value)
681
682#define STRINGIFY(X) (#X)
683#define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X);
684 switch (Object->Header.Machine) {
685 case ELF::EM_AARCH64:
686#undef AARCH64_DYNAMIC_TAG
687#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
688#include "llvm/BinaryFormat/DynamicTags.def"
689#undef AARCH64_DYNAMIC_TAG
690#define AARCH64_DYNAMIC_TAG(name, value)
691 break;
692 case ELF::EM_MIPS:
693#undef MIPS_DYNAMIC_TAG
694#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
695#include "llvm/BinaryFormat/DynamicTags.def"
696#undef MIPS_DYNAMIC_TAG
697#define MIPS_DYNAMIC_TAG(name, value)
698 break;
699 case ELF::EM_HEXAGON:
700#undef HEXAGON_DYNAMIC_TAG
701#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
702#include "llvm/BinaryFormat/DynamicTags.def"
703#undef HEXAGON_DYNAMIC_TAG
704#define HEXAGON_DYNAMIC_TAG(name, value)
705 break;
706 case ELF::EM_PPC:
707#undef PPC_DYNAMIC_TAG
708#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
709#include "llvm/BinaryFormat/DynamicTags.def"
710#undef PPC_DYNAMIC_TAG
711#define PPC_DYNAMIC_TAG(name, value)
712 break;
713 case ELF::EM_PPC64:
714#undef PPC64_DYNAMIC_TAG
715#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
716#include "llvm/BinaryFormat/DynamicTags.def"
717#undef PPC64_DYNAMIC_TAG
718#define PPC64_DYNAMIC_TAG(name, value)
719 break;
720 default:
721#include "llvm/BinaryFormat/DynamicTags.def"
722 break;
723 }
724#undef AARCH64_DYNAMIC_TAG
725#undef MIPS_DYNAMIC_TAG
726#undef HEXAGON_DYNAMIC_TAG
727#undef PPC_DYNAMIC_TAG
728#undef PPC64_DYNAMIC_TAG
729#undef DYNAMIC_TAG_MARKER
730#undef STRINGIFY
731#undef DYNAMIC_TAG
732
733 IO.enumFallback<Hex64>(Value);
734}
735
736void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
737 IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
738#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
739 ECase(REG_NONE);
740 ECase(REG_32);
741 ECase(REG_64);
742 ECase(REG_128);
743#undef ECase
744}
745
746void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration(
747 IO &IO, ELFYAML::MIPS_ABI_FP &Value) {
748#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X)
749 ECase(FP_ANY);
750 ECase(FP_DOUBLE);
751 ECase(FP_SINGLE);
752 ECase(FP_SOFT);
753 ECase(FP_OLD_64);
754 ECase(FP_XX);
755 ECase(FP_64);
756 ECase(FP_64A);
757#undef ECase
758}
759
760void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration(
761 IO &IO, ELFYAML::MIPS_AFL_EXT &Value) {
762#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
763 ECase(EXT_NONE);
764 ECase(EXT_XLR);
765 ECase(EXT_OCTEON2);
766 ECase(EXT_OCTEONP);
767 ECase(EXT_LOONGSON_3A);
768 ECase(EXT_OCTEON);
769 ECase(EXT_5900);
770 ECase(EXT_4650);
771 ECase(EXT_4010);
772 ECase(EXT_4100);
773 ECase(EXT_3900);
774 ECase(EXT_10000);
775 ECase(EXT_SB1);
776 ECase(EXT_4111);
777 ECase(EXT_4120);
778 ECase(EXT_5400);
779 ECase(EXT_5500);
780 ECase(EXT_LOONGSON_2E);
781 ECase(EXT_LOONGSON_2F);
782 ECase(EXT_OCTEON3);
783#undef ECase
784}
785
786void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
787 IO &IO, ELFYAML::MIPS_ISA &Value) {
788 IO.enumCase(Value, "MIPS1", 1);
789 IO.enumCase(Value, "MIPS2", 2);
790 IO.enumCase(Value, "MIPS3", 3);
791 IO.enumCase(Value, "MIPS4", 4);
792 IO.enumCase(Value, "MIPS5", 5);
793 IO.enumCase(Value, "MIPS32", 32);
794 IO.enumCase(Value, "MIPS64", 64);
795}
796
797void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset(
798 IO &IO, ELFYAML::MIPS_AFL_ASE &Value) {
799#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X)
800 BCase(DSP);
801 BCase(DSPR2);
802 BCase(EVA);
803 BCase(MCU);
804 BCase(MDMX);
805 BCase(MIPS3D);
806 BCase(MT);
807 BCase(SMARTMIPS);
808 BCase(VIRT);
809 BCase(MSA);
810 BCase(MIPS16);
811 BCase(MICROMIPS);
812 BCase(XPA);
813#undef BCase
814}
815
816void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
817 IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) {
818#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X)
819 BCase(ODDSPREG);
820#undef BCase
821}
822
823void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
824 ELFYAML::FileHeader &FileHdr) {
825 IO.mapRequired("Class", FileHdr.Class);
826 IO.mapRequired("Data", FileHdr.Data);
827 IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
828 IO.mapOptional("ABIVersion", FileHdr.ABIVersion, Hex8(0));
829 IO.mapRequired("Type", FileHdr.Type);
830 IO.mapRequired("Machine", FileHdr.Machine);
831 IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
832 IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
833
834 IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
835 IO.mapOptional("SHOff", FileHdr.SHOff);
836 IO.mapOptional("SHNum", FileHdr.SHNum);
837 IO.mapOptional("SHStrNdx", FileHdr.SHStrNdx);
838}
839
840void MappingTraits<ELFYAML::ProgramHeader>::mapping(
841 IO &IO, ELFYAML::ProgramHeader &Phdr) {
842 IO.mapRequired("Type", Phdr.Type);
843 IO.mapOptional("Flags", Phdr.Flags, ELFYAML::ELF_PF(0));
844 IO.mapOptional("Sections", Phdr.Sections);
845 IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
846 IO.mapOptional("PAddr", Phdr.PAddr, Hex64(0));
847 IO.mapOptional("Align", Phdr.Align);
848 IO.mapOptional("FileSize", Phdr.FileSize);
849 IO.mapOptional("MemSize", Phdr.MemSize);
850 IO.mapOptional("Offset", Phdr.Offset);
851}
852
853LLVM_YAML_STRONG_TYPEDEF(StringRef, StOtherPiece)struct StOtherPiece { StOtherPiece() = default; StOtherPiece(
const StringRef v) : value(v) {} StOtherPiece(const StOtherPiece
&v) = default; StOtherPiece &operator=(const StOtherPiece
&rhs) = default; StOtherPiece &operator=(const StringRef
&rhs) { value = rhs; return *this; } operator const StringRef
& () const { return value; } bool operator==(const StOtherPiece
&rhs) const { return value == rhs.value; } bool operator
==(const StringRef &rhs) const { return value == rhs; } bool
operator<(const StOtherPiece &rhs) const { return value
< rhs.value; } StringRef value; using BaseType = StringRef
; };
854
855template <> struct ScalarTraits<StOtherPiece> {
856 static void output(const StOtherPiece &Val, void *, raw_ostream &Out) {
857 Out << Val;
858 }
859 static StringRef input(StringRef Scalar, void *, StOtherPiece &Val) {
860 Val = Scalar;
861 return {};
862 }
863 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
864};
865template <> struct SequenceElementTraits<StOtherPiece> {
866 static const bool flow = true;
867};
868
869template <> struct ScalarTraits<ELFYAML::YAMLFlowString> {
870 static void output(const ELFYAML::YAMLFlowString &Val, void *,
871 raw_ostream &Out) {
872 Out << Val;
873 }
874 static StringRef input(StringRef Scalar, void *,
875 ELFYAML::YAMLFlowString &Val) {
876 Val = Scalar;
877 return {};
878 }
879 static QuotingType mustQuote(StringRef S) {
880 return ScalarTraits<StringRef>::mustQuote(S);
881 }
882};
883template <> struct SequenceElementTraits<ELFYAML::YAMLFlowString> {
884 static const bool flow = true;
885};
886
887namespace {
888
889struct NormalizedOther {
890 NormalizedOther(IO &IO) : YamlIO(IO) {}
891 NormalizedOther(IO &IO, Optional<uint8_t> Original) : YamlIO(IO) {
892 assert(Original && "This constructor is only used for outputting YAML and "((Original && "This constructor is only used for outputting YAML and "
"assumes a non-empty Original") ? static_cast<void> (0
) : __assert_fail ("Original && \"This constructor is only used for outputting YAML and \" \"assumes a non-empty Original\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 893, __PRETTY_FUNCTION__))
893 "assumes a non-empty Original")((Original && "This constructor is only used for outputting YAML and "
"assumes a non-empty Original") ? static_cast<void> (0
) : __assert_fail ("Original && \"This constructor is only used for outputting YAML and \" \"assumes a non-empty Original\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 893, __PRETTY_FUNCTION__))
;
894 std::vector<StOtherPiece> Ret;
895 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
896 for (std::pair<StringRef, uint8_t> &P :
897 getFlags(Object->Header.Machine).takeVector()) {
898 uint8_t FlagValue = P.second;
899 if ((*Original & FlagValue) != FlagValue)
900 continue;
901 *Original &= ~FlagValue;
902 Ret.push_back({P.first});
903 }
904
905 if (*Original != 0) {
906 UnknownFlagsHolder = std::to_string(*Original);
907 Ret.push_back({UnknownFlagsHolder});
908 }
909
910 if (!Ret.empty())
911 Other = std::move(Ret);
912 }
913
914 uint8_t toValue(StringRef Name) {
915 const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
916 MapVector<StringRef, uint8_t> Flags = getFlags(Object->Header.Machine);
917
918 auto It = Flags.find(Name);
919 if (It != Flags.end())
920 return It->second;
921
922 uint8_t Val;
923 if (to_integer(Name, Val))
924 return Val;
925
926 YamlIO.setError("an unknown value is used for symbol's 'Other' field: " +
927 Name);
928 return 0;
929 }
930
931 Optional<uint8_t> denormalize(IO &) {
932 if (!Other)
933 return None;
934 uint8_t Ret = 0;
935 for (StOtherPiece &Val : *Other)
936 Ret |= toValue(Val);
937 return Ret;
938 }
939
940 // st_other field is used to encode symbol visibility and platform-dependent
941 // flags and values. This method returns a name to value map that is used for
942 // parsing and encoding this field.
943 MapVector<StringRef, uint8_t> getFlags(unsigned EMachine) {
944 MapVector<StringRef, uint8_t> Map;
945 // STV_* values are just enumeration values. We add them in a reversed order
946 // because when we convert the st_other to named constants when printing
947 // YAML we want to use a maximum number of bits on each step:
948 // when we have st_other == 3, we want to print it as STV_PROTECTED (3), but
949 // not as STV_HIDDEN (2) + STV_INTERNAL (1).
950 Map["STV_PROTECTED"] = ELF::STV_PROTECTED;
951 Map["STV_HIDDEN"] = ELF::STV_HIDDEN;
952 Map["STV_INTERNAL"] = ELF::STV_INTERNAL;
953 // STV_DEFAULT is used to represent the default visibility and has a value
954 // 0. We want to be able to read it from YAML documents, but there is no
955 // reason to print it.
956 if (!YamlIO.outputting())
957 Map["STV_DEFAULT"] = ELF::STV_DEFAULT;
958
959 // MIPS is not consistent. All of the STO_MIPS_* values are bit flags,
960 // except STO_MIPS_MIPS16 which overlaps them. It should be checked and
961 // consumed first when we print the output, because we do not want to print
962 // any other flags that have the same bits instead.
963 if (EMachine == ELF::EM_MIPS) {
964 Map["STO_MIPS_MIPS16"] = ELF::STO_MIPS_MIPS16;
965 Map["STO_MIPS_MICROMIPS"] = ELF::STO_MIPS_MICROMIPS;
966 Map["STO_MIPS_PIC"] = ELF::STO_MIPS_PIC;
967 Map["STO_MIPS_PLT"] = ELF::STO_MIPS_PLT;
968 Map["STO_MIPS_OPTIONAL"] = ELF::STO_MIPS_OPTIONAL;
969 }
970 return Map;
971 }
972
973 IO &YamlIO;
974 Optional<std::vector<StOtherPiece>> Other;
975 std::string UnknownFlagsHolder;
976};
977
978} // end anonymous namespace
979
980void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
981 IO.mapOptional("Name", Symbol.Name, StringRef());
982 IO.mapOptional("NameIndex", Symbol.NameIndex);
983 IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
984 IO.mapOptional("Section", Symbol.Section, StringRef());
985 IO.mapOptional("Index", Symbol.Index);
986 IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
987 IO.mapOptional("Value", Symbol.Value, Hex64(0));
988 IO.mapOptional("Size", Symbol.Size, Hex64(0));
989
990 // Symbol's Other field is a bit special. It is usually a field that
991 // represents st_other and holds the symbol visibility. However, on some
992 // platforms, it can contain bit fields and regular values, or even sometimes a
993 // crazy mix of them (see comments for NormalizedOther). Because of this, we
994 // need special handling.
995 MappingNormalization<NormalizedOther, Optional<uint8_t>> Keys(IO,
996 Symbol.Other);
997 IO.mapOptional("Other", Keys->Other);
998}
999
1000StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
1001 ELFYAML::Symbol &Symbol) {
1002 if (Symbol.Index && Symbol.Section.data())
1003 return "Index and Section cannot both be specified for Symbol";
1004 if (Symbol.NameIndex && !Symbol.Name.empty())
1005 return "Name and NameIndex cannot both be specified for Symbol";
1006 return StringRef();
1007}
1008
1009static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
1010 IO.mapOptional("Name", Section.Name, StringRef());
1011 IO.mapRequired("Type", Section.Type);
1012 IO.mapOptional("Flags", Section.Flags);
1013 IO.mapOptional("Address", Section.Address, Hex64(0));
1014 IO.mapOptional("Link", Section.Link, StringRef());
1015 IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
1016 IO.mapOptional("EntSize", Section.EntSize);
1017
1018 // obj2yaml does not dump these fields. They are expected to be empty when we
1019 // are producing YAML, because yaml2obj sets appropriate values for them
1020 // automatically when they are not explicitly defined.
1021 assert(!IO.outputting() ||((!IO.outputting() || (!Section.ShOffset.hasValue() &&
!Section.ShSize.hasValue() && !Section.ShName.hasValue
() && !Section.ShFlags.hasValue())) ? static_cast<
void> (0) : __assert_fail ("!IO.outputting() || (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue() && !Section.ShName.hasValue() && !Section.ShFlags.hasValue())"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1023, __PRETTY_FUNCTION__))
1022 (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue() &&((!IO.outputting() || (!Section.ShOffset.hasValue() &&
!Section.ShSize.hasValue() && !Section.ShName.hasValue
() && !Section.ShFlags.hasValue())) ? static_cast<
void> (0) : __assert_fail ("!IO.outputting() || (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue() && !Section.ShName.hasValue() && !Section.ShFlags.hasValue())"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1023, __PRETTY_FUNCTION__))
1023 !Section.ShName.hasValue() && !Section.ShFlags.hasValue()))((!IO.outputting() || (!Section.ShOffset.hasValue() &&
!Section.ShSize.hasValue() && !Section.ShName.hasValue
() && !Section.ShFlags.hasValue())) ? static_cast<
void> (0) : __assert_fail ("!IO.outputting() || (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue() && !Section.ShName.hasValue() && !Section.ShFlags.hasValue())"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1023, __PRETTY_FUNCTION__))
;
1024 IO.mapOptional("ShName", Section.ShName);
1025 IO.mapOptional("ShOffset", Section.ShOffset);
1026 IO.mapOptional("ShSize", Section.ShSize);
1027 IO.mapOptional("ShFlags", Section.ShFlags);
1028}
1029
1030static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
1031 commonSectionMapping(IO, Section);
1032 IO.mapOptional("Entries", Section.Entries);
1033 IO.mapOptional("Content", Section.Content);
1034}
1035
1036static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
1037 commonSectionMapping(IO, Section);
1038 IO.mapOptional("Content", Section.Content);
1039 IO.mapOptional("Size", Section.Size);
1040 IO.mapOptional("Info", Section.Info);
1041}
1042
1043static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) {
1044 commonSectionMapping(IO, Section);
1045 IO.mapOptional("Content", Section.Content);
1046 IO.mapOptional("Size", Section.Size);
1047 IO.mapOptional("Entries", Section.Entries);
1048}
1049
1050static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
1051 commonSectionMapping(IO, Section);
1052 IO.mapOptional("Content", Section.Content);
1053 IO.mapOptional("Bucket", Section.Bucket);
1054 IO.mapOptional("Chain", Section.Chain);
1055 IO.mapOptional("Size", Section.Size);
1056}
1057
1058static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) {
1059 commonSectionMapping(IO, Section);
1060 IO.mapOptional("Content", Section.Content);
1061 IO.mapOptional("Size", Section.Size);
1062 IO.mapOptional("Notes", Section.Notes);
1063}
1064
1065
1066static void sectionMapping(IO &IO, ELFYAML::GnuHashSection &Section) {
1067 commonSectionMapping(IO, Section);
1068 IO.mapOptional("Content", Section.Content);
1069 IO.mapOptional("Header", Section.Header);
1070 IO.mapOptional("BloomFilter", Section.BloomFilter);
1071 IO.mapOptional("HashBuckets", Section.HashBuckets);
1072 IO.mapOptional("HashValues", Section.HashValues);
1073}
1074static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
1075 commonSectionMapping(IO, Section);
1076 IO.mapOptional("Size", Section.Size, Hex64(0));
1077}
1078
1079static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
1080 commonSectionMapping(IO, Section);
1081 IO.mapRequired("Info", Section.Info);
1082 IO.mapOptional("Entries", Section.Entries);
1083 IO.mapOptional("Content", Section.Content);
1084}
1085
1086static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
1087 commonSectionMapping(IO, Section);
1088 IO.mapRequired("Entries", Section.Entries);
1089}
1090
1091static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
1092 commonSectionMapping(IO, Section);
1093 IO.mapRequired("Info", Section.Info);
1094 IO.mapOptional("Dependencies", Section.VerneedV);
1095 IO.mapOptional("Content", Section.Content);
1096}
1097
1098static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
1099 commonSectionMapping(IO, Section);
1100 IO.mapOptional("Info", Section.RelocatableSec, StringRef());
1101 IO.mapOptional("Relocations", Section.Relocations);
1102}
1103
1104static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) {
1105 commonSectionMapping(IO, Group);
1106 IO.mapOptional("Info", Group.Signature);
1107 IO.mapRequired("Members", Group.Members);
1108}
1109
1110static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) {
1111 commonSectionMapping(IO, Section);
1112 IO.mapRequired("Entries", Section.Entries);
1113}
1114
1115static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) {
1116 commonSectionMapping(IO, Section);
1117 IO.mapOptional("Content", Section.Content);
1118 IO.mapOptional("Size", Section.Size);
1119 IO.mapOptional("Symbols", Section.Symbols);
1120}
1121
1122static void fillMapping(IO &IO, ELFYAML::Fill &Fill) {
1123 IO.mapOptional("Name", Fill.Name, StringRef());
1124 IO.mapOptional("Pattern", Fill.Pattern);
1125 IO.mapRequired("Size", Fill.Size);
1126}
1127
1128static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) {
1129 commonSectionMapping(IO, Section);
1130 IO.mapOptional("Options", Section.Options);
1131 IO.mapOptional("Content", Section.Content);
1132}
1133
1134static void sectionMapping(IO &IO,
1135 ELFYAML::DependentLibrariesSection &Section) {
1136 commonSectionMapping(IO, Section);
1137 IO.mapOptional("Libraries", Section.Libs);
1138 IO.mapOptional("Content", Section.Content);
1139}
1140
1141void MappingTraits<ELFYAML::SectionOrType>::mapping(
1142 IO &IO, ELFYAML::SectionOrType &sectionOrType) {
1143 IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
1144}
1145
1146void MappingTraits<ELFYAML::SectionName>::mapping(
1147 IO &IO, ELFYAML::SectionName &sectionName) {
1148 IO.mapRequired("Section", sectionName.Section);
1149}
1150
1151static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
1152 commonSectionMapping(IO, Section);
1153 IO.mapOptional("Version", Section.Version, Hex16(0));
1154 IO.mapRequired("ISA", Section.ISALevel);
1155 IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
1156 IO.mapOptional("ISAExtension", Section.ISAExtension,
1157 ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
1158 IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
1159 IO.mapOptional("FpABI", Section.FpABI,
1160 ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
1161 IO.mapOptional("GPRSize", Section.GPRSize,
1162 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1163 IO.mapOptional("CPR1Size", Section.CPR1Size,
1164 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1165 IO.mapOptional("CPR2Size", Section.CPR2Size,
1166 ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
1167 IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
1168 IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
1169}
1170
1171void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
1172 IO &IO, std::unique_ptr<ELFYAML::Chunk> &Section) {
1173 ELFYAML::ELF_SHT Type;
1
Calling defaulted default constructor for 'ELF_SHT'
3
Returning from default constructor for 'ELF_SHT'
1174 if (IO.outputting()) {
4
Assuming the condition is false
5
Taking false branch
1175 Type = cast<ELFYAML::Section>(Section.get())->Type;
1176 } else {
1177 // When the Type string does not have a "SHT_" prefix, we know it is not a
1178 // description of a regular ELF output section. Currently, we have one
1179 // special type named "Fill". See comments for Fill.
1180 StringRef StrType;
1181 IO.mapRequired("Type", StrType);
1182 if (StrType == "Fill") {
6
Assuming the condition is false
7
Taking false branch
1183 Section.reset(new ELFYAML::Fill());
1184 fillMapping(IO, *cast<ELFYAML::Fill>(Section.get()));
1185 return;
1186 }
1187
1188 IO.mapRequired("Type", Type);
8
Calling 'IO::mapRequired'
1189 }
1190
1191 switch (Type) {
1192 case ELF::SHT_DYNAMIC:
1193 if (!IO.outputting())
1194 Section.reset(new ELFYAML::DynamicSection());
1195 sectionMapping(IO, *cast<ELFYAML::DynamicSection>(Section.get()));
1196 break;
1197 case ELF::SHT_REL:
1198 case ELF::SHT_RELA:
1199 if (!IO.outputting())
1200 Section.reset(new ELFYAML::RelocationSection());
1201 sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
1202 break;
1203 case ELF::SHT_GROUP:
1204 if (!IO.outputting())
1205 Section.reset(new ELFYAML::Group());
1206 groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get()));
1207 break;
1208 case ELF::SHT_NOBITS:
1209 if (!IO.outputting())
1210 Section.reset(new ELFYAML::NoBitsSection());
1211 sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get()));
1212 break;
1213 case ELF::SHT_HASH:
1214 if (!IO.outputting())
1215 Section.reset(new ELFYAML::HashSection());
1216 sectionMapping(IO, *cast<ELFYAML::HashSection>(Section.get()));
1217 break;
1218 case ELF::SHT_NOTE:
1219 if (!IO.outputting())
1220 Section.reset(new ELFYAML::NoteSection());
1221 sectionMapping(IO, *cast<ELFYAML::NoteSection>(Section.get()));
1222 break;
1223 case ELF::SHT_GNU_HASH:
1224 if (!IO.outputting())
1225 Section.reset(new ELFYAML::GnuHashSection());
1226 sectionMapping(IO, *cast<ELFYAML::GnuHashSection>(Section.get()));
1227 break;
1228 case ELF::SHT_MIPS_ABIFLAGS:
1229 if (!IO.outputting())
1230 Section.reset(new ELFYAML::MipsABIFlags());
1231 sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
1232 break;
1233 case ELF::SHT_GNU_verdef:
1234 if (!IO.outputting())
1235 Section.reset(new ELFYAML::VerdefSection());
1236 sectionMapping(IO, *cast<ELFYAML::VerdefSection>(Section.get()));
1237 break;
1238 case ELF::SHT_GNU_versym:
1239 if (!IO.outputting())
1240 Section.reset(new ELFYAML::SymverSection());
1241 sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
1242 break;
1243 case ELF::SHT_GNU_verneed:
1244 if (!IO.outputting())
1245 Section.reset(new ELFYAML::VerneedSection());
1246 sectionMapping(IO, *cast<ELFYAML::VerneedSection>(Section.get()));
1247 break;
1248 case ELF::SHT_SYMTAB_SHNDX:
1249 if (!IO.outputting())
1250 Section.reset(new ELFYAML::SymtabShndxSection());
1251 sectionMapping(IO, *cast<ELFYAML::SymtabShndxSection>(Section.get()));
1252 break;
1253 case ELF::SHT_LLVM_ADDRSIG:
1254 if (!IO.outputting())
1255 Section.reset(new ELFYAML::AddrsigSection());
1256 sectionMapping(IO, *cast<ELFYAML::AddrsigSection>(Section.get()));
1257 break;
1258 case ELF::SHT_LLVM_LINKER_OPTIONS:
1259 if (!IO.outputting())
1260 Section.reset(new ELFYAML::LinkerOptionsSection());
1261 sectionMapping(IO, *cast<ELFYAML::LinkerOptionsSection>(Section.get()));
1262 break;
1263 case ELF::SHT_LLVM_DEPENDENT_LIBRARIES:
1264 if (!IO.outputting())
1265 Section.reset(new ELFYAML::DependentLibrariesSection());
1266 sectionMapping(IO,
1267 *cast<ELFYAML::DependentLibrariesSection>(Section.get()));
1268 break;
1269 default:
1270 if (!IO.outputting()) {
1271 StringRef Name;
1272 IO.mapOptional("Name", Name, StringRef());
1273 Name = ELFYAML::dropUniqueSuffix(Name);
1274
1275 if (ELFYAML::StackSizesSection::nameMatches(Name))
1276 Section = std::make_unique<ELFYAML::StackSizesSection>();
1277 else
1278 Section = std::make_unique<ELFYAML::RawContentSection>();
1279 }
1280
1281 if (auto S = dyn_cast<ELFYAML::RawContentSection>(Section.get()))
1282 sectionMapping(IO, *S);
1283 else
1284 sectionMapping(IO, *cast<ELFYAML::StackSizesSection>(Section.get()));
1285 }
1286}
1287
1288StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
1289 IO &io, std::unique_ptr<ELFYAML::Chunk> &C) {
1290 if (const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(C.get())) {
1291 if (RawSection->Size && RawSection->Content &&
1292 (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size())
1293 return "Section size must be greater than or equal to the content size";
1294 if (RawSection->Flags && RawSection->ShFlags)
1295 return "ShFlags and Flags cannot be used together";
1296 return {};
1297 }
1298
1299 if (const auto *SS = dyn_cast<ELFYAML::StackSizesSection>(C.get())) {
1300 if (!SS->Entries && !SS->Content && !SS->Size)
1301 return ".stack_sizes: one of Content, Entries and Size must be specified";
1302
1303 if (SS->Size && SS->Content &&
1304 (uint64_t)(*SS->Size) < SS->Content->binary_size())
1305 return ".stack_sizes: Size must be greater than or equal to the content "
1306 "size";
1307
1308 // We accept Content, Size or both together when there are no Entries.
1309 if (!SS->Entries)
1310 return {};
1311
1312 if (SS->Size)
1313 return ".stack_sizes: Size and Entries cannot be used together";
1314 if (SS->Content)
1315 return ".stack_sizes: Content and Entries cannot be used together";
1316 return {};
1317 }
1318
1319 if (const auto *HS = dyn_cast<ELFYAML::HashSection>(C.get())) {
1320 if (!HS->Content && !HS->Bucket && !HS->Chain && !HS->Size)
1321 return "one of \"Content\", \"Size\", \"Bucket\" or \"Chain\" must be "
1322 "specified";
1323
1324 if (HS->Content || HS->Size) {
1325 if (HS->Size && HS->Content &&
1326 (uint64_t)*HS->Size < HS->Content->binary_size())
1327 return "\"Size\" must be greater than or equal to the content "
1328 "size";
1329
1330 if (HS->Bucket)
1331 return "\"Bucket\" cannot be used with \"Content\" or \"Size\"";
1332 if (HS->Chain)
1333 return "\"Chain\" cannot be used with \"Content\" or \"Size\"";
1334 return {};
1335 }
1336
1337 if ((HS->Bucket && !HS->Chain) || (!HS->Bucket && HS->Chain))
1338 return "\"Bucket\" and \"Chain\" must be used together";
1339 return {};
1340 }
1341
1342 if (const auto *Sec = dyn_cast<ELFYAML::AddrsigSection>(C.get())) {
1343 if (!Sec->Symbols && !Sec->Content && !Sec->Size)
1344 return "one of \"Content\", \"Size\" or \"Symbols\" must be specified";
1345
1346 if (Sec->Content || Sec->Size) {
1347 if (Sec->Size && Sec->Content &&
1348 (uint64_t)*Sec->Size < Sec->Content->binary_size())
1349 return "\"Size\" must be greater than or equal to the content "
1350 "size";
1351
1352 if (Sec->Symbols)
1353 return "\"Symbols\" cannot be used with \"Content\" or \"Size\"";
1354 return {};
1355 }
1356
1357 if (!Sec->Symbols)
1358 return {};
1359
1360 for (const ELFYAML::AddrsigSymbol &AS : *Sec->Symbols)
1361 if (AS.Index && AS.Name)
1362 return "\"Index\" and \"Name\" cannot be used together when defining a "
1363 "symbol";
1364 return {};
1365 }
1366
1367 if (const auto *NS = dyn_cast<ELFYAML::NoteSection>(C.get())) {
1368 if (!NS->Content && !NS->Size && !NS->Notes)
1369 return "one of \"Content\", \"Size\" or \"Notes\" must be "
1370 "specified";
1371
1372 if (!NS->Content && !NS->Size)
1373 return {};
1374
1375 if (NS->Size && NS->Content &&
1376 (uint64_t)*NS->Size < NS->Content->binary_size())
1377 return "\"Size\" must be greater than or equal to the content "
1378 "size";
1379
1380 if (NS->Notes)
1381 return "\"Notes\" cannot be used with \"Content\" or \"Size\"";
1382 return {};
1383 }
1384
1385 if (const auto *Sec = dyn_cast<ELFYAML::GnuHashSection>(C.get())) {
1386 if (!Sec->Content && !Sec->Header && !Sec->BloomFilter &&
1387 !Sec->HashBuckets && !Sec->HashValues)
1388 return "either \"Content\" or \"Header\", \"BloomFilter\", "
1389 "\"HashBuckets\" and \"HashBuckets\" must be specified";
1390
1391 if (Sec->Header || Sec->BloomFilter || Sec->HashBuckets ||
1392 Sec->HashValues) {
1393 if (!Sec->Header || !Sec->BloomFilter || !Sec->HashBuckets ||
1394 !Sec->HashValues)
1395 return "\"Header\", \"BloomFilter\", "
1396 "\"HashBuckets\" and \"HashValues\" must be used together";
1397 if (Sec->Content)
1398 return "\"Header\", \"BloomFilter\", "
1399 "\"HashBuckets\" and \"HashValues\" can't be used together with "
1400 "\"Content\"";
1401 return {};
1402 }
1403
1404 // Only Content is specified.
1405 return {};
1406 }
1407
1408 if (const auto *Sec = dyn_cast<ELFYAML::LinkerOptionsSection>(C.get())) {
1409 if (Sec->Options && Sec->Content)
1410 return "\"Options\" and \"Content\" can't be used together";
1411 return {};
1412 }
1413
1414 if (const auto *Sec = dyn_cast<ELFYAML::DependentLibrariesSection>(C.get())) {
1415 if (Sec->Libs && Sec->Content)
1416 return "SHT_LLVM_DEPENDENT_LIBRARIES: \"Libraries\" and \"Content\" "
1417 "can't "
1418 "be used together";
1419 return {};
1420 }
1421
1422 if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) {
1423 if (!F->Pattern)
1424 return {};
1425 if (F->Pattern->binary_size() != 0 && !F->Size)
1426 return "\"Size\" can't be 0 when \"Pattern\" is not empty";
1427 return {};
1428 }
1429
1430 if (const auto *VD = dyn_cast<ELFYAML::VerdefSection>(C.get())) {
1431 if (VD->Entries && VD->Content)
1432 return "SHT_GNU_verdef: \"Entries\" and \"Content\" can't be used "
1433 "together";
1434 return {};
1435 }
1436
1437 if (const auto *VD = dyn_cast<ELFYAML::VerneedSection>(C.get())) {
1438 if (VD->VerneedV && VD->Content)
1439 return "SHT_GNU_verneed: \"Dependencies\" and \"Content\" can't be used "
1440 "together";
1441 return {};
1442 }
1443
1444 return {};
1445}
1446
1447namespace {
1448
1449struct NormalizedMips64RelType {
1450 NormalizedMips64RelType(IO &)
1451 : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1452 Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1453 Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
1454 SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
1455 NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
1456 : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
1457 Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
1458
1459 ELFYAML::ELF_REL denormalize(IO &) {
1460 ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
1461 return Res;
1462 }
1463
1464 ELFYAML::ELF_REL Type;
1465 ELFYAML::ELF_REL Type2;
1466 ELFYAML::ELF_REL Type3;
1467 ELFYAML::ELF_RSS SpecSym;
1468};
1469
1470} // end anonymous namespace
1471
1472void MappingTraits<ELFYAML::StackSizeEntry>::mapping(
1473 IO &IO, ELFYAML::StackSizeEntry &E) {
1474 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1474, __PRETTY_FUNCTION__))
;
1475 IO.mapOptional("Address", E.Address, Hex64(0));
1476 IO.mapRequired("Size", E.Size);
1477}
1478
1479void MappingTraits<ELFYAML::GnuHashHeader>::mapping(IO &IO,
1480 ELFYAML::GnuHashHeader &E) {
1481 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1481, __PRETTY_FUNCTION__))
;
1482 IO.mapOptional("NBuckets", E.NBuckets);
1483 IO.mapRequired("SymNdx", E.SymNdx);
1484 IO.mapOptional("MaskWords", E.MaskWords);
1485 IO.mapRequired("Shift2", E.Shift2);
1486}
1487
1488void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
1489 ELFYAML::DynamicEntry &Rel) {
1490 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1490, __PRETTY_FUNCTION__))
;
1491
1492 IO.mapRequired("Tag", Rel.Tag);
1493 IO.mapRequired("Value", Rel.Val);
1494}
1495
1496void MappingTraits<ELFYAML::NoteEntry>::mapping(IO &IO, ELFYAML::NoteEntry &N) {
1497 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1497, __PRETTY_FUNCTION__))
;
1498
1499 IO.mapOptional("Name", N.Name);
1500 IO.mapOptional("Desc", N.Desc);
1501 IO.mapRequired("Type", N.Type);
1502}
1503
1504void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
1505 ELFYAML::VerdefEntry &E) {
1506 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1506, __PRETTY_FUNCTION__))
;
1507
1508 IO.mapRequired("Version", E.Version);
1509 IO.mapRequired("Flags", E.Flags);
1510 IO.mapRequired("VersionNdx", E.VersionNdx);
1511 IO.mapRequired("Hash", E.Hash);
1512 IO.mapRequired("Names", E.VerNames);
1513}
1514
1515void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
1516 ELFYAML::VerneedEntry &E) {
1517 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1517, __PRETTY_FUNCTION__))
;
1518
1519 IO.mapRequired("Version", E.Version);
1520 IO.mapRequired("File", E.File);
1521 IO.mapRequired("Entries", E.AuxV);
1522}
1523
1524void MappingTraits<ELFYAML::VernauxEntry>::mapping(IO &IO,
1525 ELFYAML::VernauxEntry &E) {
1526 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1526, __PRETTY_FUNCTION__))
;
1527
1528 IO.mapRequired("Name", E.Name);
1529 IO.mapRequired("Hash", E.Hash);
1530 IO.mapRequired("Flags", E.Flags);
1531 IO.mapRequired("Other", E.Other);
1532}
1533
1534void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
1535 ELFYAML::Relocation &Rel) {
1536 const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
1537 assert(Object && "The IO context is not initialized")((Object && "The IO context is not initialized") ? static_cast
<void> (0) : __assert_fail ("Object && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1537, __PRETTY_FUNCTION__))
;
1538
1539 IO.mapRequired("Offset", Rel.Offset);
1540 IO.mapOptional("Symbol", Rel.Symbol);
1541
1542 if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
1543 Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
1544 MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
1545 IO, Rel.Type);
1546 IO.mapRequired("Type", Key->Type);
1547 IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1548 IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
1549 IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
1550 } else
1551 IO.mapRequired("Type", Rel.Type);
1552
1553 IO.mapOptional("Addend", Rel.Addend, (int64_t)0);
1554}
1555
1556void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
1557 assert(!IO.getContext() && "The IO context is initialized already")((!IO.getContext() && "The IO context is initialized already"
) ? static_cast<void> (0) : __assert_fail ("!IO.getContext() && \"The IO context is initialized already\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1557, __PRETTY_FUNCTION__))
;
1558 IO.setContext(&Object);
1559 IO.mapTag("!ELF", true);
1560 IO.mapRequired("FileHeader", Object.Header);
1561 IO.mapOptional("ProgramHeaders", Object.ProgramHeaders);
1562 IO.mapOptional("Sections", Object.Chunks);
1563 IO.mapOptional("Symbols", Object.Symbols);
1564 IO.mapOptional("DynamicSymbols", Object.DynamicSymbols);
1565 IO.setContext(nullptr);
1566}
1567
1568void MappingTraits<ELFYAML::AddrsigSymbol>::mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym) {
1569 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1569, __PRETTY_FUNCTION__))
;
1570 IO.mapOptional("Name", Sym.Name);
1571 IO.mapOptional("Index", Sym.Index);
1572}
1573
1574void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO,
1575 ELFYAML::LinkerOption &Opt) {
1576 assert(IO.getContext() && "The IO context is not initialized")((IO.getContext() && "The IO context is not initialized"
) ? static_cast<void> (0) : __assert_fail ("IO.getContext() && \"The IO context is not initialized\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/ObjectYAML/ELFYAML.cpp"
, 1576, __PRETTY_FUNCTION__))
;
1577 IO.mapRequired("Name", Opt.Key);
1578 IO.mapRequired("Value", Opt.Value);
1579}
1580
1581LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)struct MIPS_AFL_REG { MIPS_AFL_REG() = default; MIPS_AFL_REG(
const uint8_t v) : value(v) {} MIPS_AFL_REG(const MIPS_AFL_REG
&v) = default; MIPS_AFL_REG &operator=(const MIPS_AFL_REG
&rhs) = default; MIPS_AFL_REG &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const MIPS_AFL_REG
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_REG &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
1582LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)struct MIPS_ABI_FP { MIPS_ABI_FP() = default; MIPS_ABI_FP(const
uint8_t v) : value(v) {} MIPS_ABI_FP(const MIPS_ABI_FP &
v) = default; MIPS_ABI_FP &operator=(const MIPS_ABI_FP &
rhs) = default; MIPS_ABI_FP &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const MIPS_ABI_FP
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_ABI_FP &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
1583LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)struct MIPS_AFL_EXT { MIPS_AFL_EXT() = default; MIPS_AFL_EXT(
const uint32_t v) : value(v) {} MIPS_AFL_EXT(const MIPS_AFL_EXT
&v) = default; MIPS_AFL_EXT &operator=(const MIPS_AFL_EXT
&rhs) = default; MIPS_AFL_EXT &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_EXT
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_EXT &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
1584LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)struct MIPS_AFL_ASE { MIPS_AFL_ASE() = default; MIPS_AFL_ASE(
const uint32_t v) : value(v) {} MIPS_AFL_ASE(const MIPS_AFL_ASE
&v) = default; MIPS_AFL_ASE &operator=(const MIPS_AFL_ASE
&rhs) = default; MIPS_AFL_ASE &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_ASE
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_ASE &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
1585LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)struct MIPS_AFL_FLAGS1 { MIPS_AFL_FLAGS1() = default; MIPS_AFL_FLAGS1
(const uint32_t v) : value(v) {} MIPS_AFL_FLAGS1(const MIPS_AFL_FLAGS1
&v) = default; MIPS_AFL_FLAGS1 &operator=(const MIPS_AFL_FLAGS1
&rhs) = default; MIPS_AFL_FLAGS1 &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_FLAGS1
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_FLAGS1 &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
1586
1587} // end namespace yaml
1588
1589} // end namespace llvm

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ObjectYAML/ELFYAML.h

1//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- 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/// \file
10/// This file declares classes for handling the YAML representation
11/// of ELF.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OBJECTYAML_ELFYAML_H
16#define LLVM_OBJECTYAML_ELFYAML_H
17
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ObjectYAML/YAML.h"
20#include "llvm/Support/YAMLTraits.h"
21#include <cstdint>
22#include <memory>
23#include <vector>
24
25namespace llvm {
26namespace ELFYAML {
27
28StringRef dropUniqueSuffix(StringRef S);
29
30// These types are invariant across 32/64-bit ELF, so for simplicity just
31// directly give them their exact sizes. We don't need to worry about
32// endianness because these are just the types in the YAMLIO structures,
33// and are appropriately converted to the necessary endianness when
34// reading/generating binary object files.
35// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
36// the common prefix of the respective constants. E.g. ELF_EM corresponds
37// to the `e_machine` constants, like `EM_X86_64`.
38// In the future, these would probably be better suited by C++11 enum
39// class's with appropriate fixed underlying type.
40LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)struct ELF_ET { ELF_ET() = default; ELF_ET(const uint16_t v) :
value(v) {} ELF_ET(const ELF_ET &v) = default; ELF_ET &
operator=(const ELF_ET &rhs) = default; ELF_ET &operator
=(const uint16_t &rhs) { value = rhs; return *this; } operator
const uint16_t & () const { return value; } bool operator
==(const ELF_ET &rhs) const { return value == rhs.value; }
bool operator==(const uint16_t &rhs) const { return value
== rhs; } bool operator<(const ELF_ET &rhs) const { return
value < rhs.value; } uint16_t value; using BaseType = uint16_t
; };
41LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)struct ELF_PT { ELF_PT() = default; ELF_PT(const uint32_t v) :
value(v) {} ELF_PT(const ELF_PT &v) = default; ELF_PT &
operator=(const ELF_PT &rhs) = default; ELF_PT &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PT &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PT &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
42LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)struct ELF_EM { ELF_EM() = default; ELF_EM(const uint32_t v) :
value(v) {} ELF_EM(const ELF_EM &v) = default; ELF_EM &
operator=(const ELF_EM &rhs) = default; ELF_EM &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_EM &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EM &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
43LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)struct ELF_ELFCLASS { ELF_ELFCLASS() = default; ELF_ELFCLASS(
const uint8_t v) : value(v) {} ELF_ELFCLASS(const ELF_ELFCLASS
&v) = default; ELF_ELFCLASS &operator=(const ELF_ELFCLASS
&rhs) = default; ELF_ELFCLASS &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFCLASS
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFCLASS &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
44LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)struct ELF_ELFDATA { ELF_ELFDATA() = default; ELF_ELFDATA(const
uint8_t v) : value(v) {} ELF_ELFDATA(const ELF_ELFDATA &
v) = default; ELF_ELFDATA &operator=(const ELF_ELFDATA &
rhs) = default; ELF_ELFDATA &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const ELF_ELFDATA
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFDATA &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
45LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)struct ELF_ELFOSABI { ELF_ELFOSABI() = default; ELF_ELFOSABI(
const uint8_t v) : value(v) {} ELF_ELFOSABI(const ELF_ELFOSABI
&v) = default; ELF_ELFOSABI &operator=(const ELF_ELFOSABI
&rhs) = default; ELF_ELFOSABI &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFOSABI
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFOSABI &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
46// Just use 64, since it can hold 32-bit values too.
47LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)struct ELF_EF { ELF_EF() = default; ELF_EF(const uint64_t v) :
value(v) {} ELF_EF(const ELF_EF &v) = default; ELF_EF &
operator=(const ELF_EF &rhs) = default; ELF_EF &operator
=(const uint64_t &rhs) { value = rhs; return *this; } operator
const uint64_t & () const { return value; } bool operator
==(const ELF_EF &rhs) const { return value == rhs.value; }
bool operator==(const uint64_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EF &rhs) const { return
value < rhs.value; } uint64_t value; using BaseType = uint64_t
; };
48// Just use 64, since it can hold 32-bit values too.
49LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)struct ELF_DYNTAG { ELF_DYNTAG() = default; ELF_DYNTAG(const uint64_t
v) : value(v) {} ELF_DYNTAG(const ELF_DYNTAG &v) = default
; ELF_DYNTAG &operator=(const ELF_DYNTAG &rhs) = default
; ELF_DYNTAG &operator=(const uint64_t &rhs) { value =
rhs; return *this; } operator const uint64_t & () const {
return value; } bool operator==(const ELF_DYNTAG &rhs) const
{ return value == rhs.value; } bool operator==(const uint64_t
&rhs) const { return value == rhs; } bool operator<(const
ELF_DYNTAG &rhs) const { return value < rhs.value; } uint64_t
value; using BaseType = uint64_t; };
50LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)struct ELF_PF { ELF_PF() = default; ELF_PF(const uint32_t v) :
value(v) {} ELF_PF(const ELF_PF &v) = default; ELF_PF &
operator=(const ELF_PF &rhs) = default; ELF_PF &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PF &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PF &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
51LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)struct ELF_SHT { ELF_SHT() = default; ELF_SHT(const uint32_t v
) : value(v) {} ELF_SHT(const ELF_SHT &v) = default; ELF_SHT
&operator=(const ELF_SHT &rhs) = default; ELF_SHT &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_SHT &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHT &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
2
Returning without writing to 'this->value'
52LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)struct ELF_REL { ELF_REL() = default; ELF_REL(const uint32_t v
) : value(v) {} ELF_REL(const ELF_REL &v) = default; ELF_REL
&operator=(const ELF_REL &rhs) = default; ELF_REL &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_REL &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_REL &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
53LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)struct ELF_RSS { ELF_RSS() = default; ELF_RSS(const uint8_t v
) : value(v) {} ELF_RSS(const ELF_RSS &v) = default; ELF_RSS
&operator=(const ELF_RSS &rhs) = default; ELF_RSS &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_RSS &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_RSS &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
54// Just use 64, since it can hold 32-bit values too.
55LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)struct ELF_SHF { ELF_SHF() = default; ELF_SHF(const uint64_t v
) : value(v) {} ELF_SHF(const ELF_SHF &v) = default; ELF_SHF
&operator=(const ELF_SHF &rhs) = default; ELF_SHF &
operator=(const uint64_t &rhs) { value = rhs; return *this
; } operator const uint64_t & () const { return value; } bool
operator==(const ELF_SHF &rhs) const { return value == rhs
.value; } bool operator==(const uint64_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHF &rhs) const
{ return value < rhs.value; } uint64_t value; using BaseType
= uint64_t; };
56LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)struct ELF_SHN { ELF_SHN() = default; ELF_SHN(const uint16_t v
) : value(v) {} ELF_SHN(const ELF_SHN &v) = default; ELF_SHN
&operator=(const ELF_SHN &rhs) = default; ELF_SHN &
operator=(const uint16_t &rhs) { value = rhs; return *this
; } operator const uint16_t & () const { return value; } bool
operator==(const ELF_SHN &rhs) const { return value == rhs
.value; } bool operator==(const uint16_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHN &rhs) const
{ return value < rhs.value; } uint16_t value; using BaseType
= uint16_t; };
57LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)struct ELF_STB { ELF_STB() = default; ELF_STB(const uint8_t v
) : value(v) {} ELF_STB(const ELF_STB &v) = default; ELF_STB
&operator=(const ELF_STB &rhs) = default; ELF_STB &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STB &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STB &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
58LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)struct ELF_STT { ELF_STT() = default; ELF_STT(const uint8_t v
) : value(v) {} ELF_STT(const ELF_STT &v) = default; ELF_STT
&operator=(const ELF_STT &rhs) = default; ELF_STT &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STT &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STT &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
59
60LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)struct MIPS_AFL_REG { MIPS_AFL_REG() = default; MIPS_AFL_REG(
const uint8_t v) : value(v) {} MIPS_AFL_REG(const MIPS_AFL_REG
&v) = default; MIPS_AFL_REG &operator=(const MIPS_AFL_REG
&rhs) = default; MIPS_AFL_REG &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const MIPS_AFL_REG
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_REG &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
61LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)struct MIPS_ABI_FP { MIPS_ABI_FP() = default; MIPS_ABI_FP(const
uint8_t v) : value(v) {} MIPS_ABI_FP(const MIPS_ABI_FP &
v) = default; MIPS_ABI_FP &operator=(const MIPS_ABI_FP &
rhs) = default; MIPS_ABI_FP &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const MIPS_ABI_FP
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_ABI_FP &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
62LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)struct MIPS_AFL_EXT { MIPS_AFL_EXT() = default; MIPS_AFL_EXT(
const uint32_t v) : value(v) {} MIPS_AFL_EXT(const MIPS_AFL_EXT
&v) = default; MIPS_AFL_EXT &operator=(const MIPS_AFL_EXT
&rhs) = default; MIPS_AFL_EXT &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_EXT
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_EXT &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
63LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)struct MIPS_AFL_ASE { MIPS_AFL_ASE() = default; MIPS_AFL_ASE(
const uint32_t v) : value(v) {} MIPS_AFL_ASE(const MIPS_AFL_ASE
&v) = default; MIPS_AFL_ASE &operator=(const MIPS_AFL_ASE
&rhs) = default; MIPS_AFL_ASE &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_ASE
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_ASE &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
64LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)struct MIPS_AFL_FLAGS1 { MIPS_AFL_FLAGS1() = default; MIPS_AFL_FLAGS1
(const uint32_t v) : value(v) {} MIPS_AFL_FLAGS1(const MIPS_AFL_FLAGS1
&v) = default; MIPS_AFL_FLAGS1 &operator=(const MIPS_AFL_FLAGS1
&rhs) = default; MIPS_AFL_FLAGS1 &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_FLAGS1
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_FLAGS1 &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
65LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)struct MIPS_ISA { MIPS_ISA() = default; MIPS_ISA(const uint32_t
v) : value(v) {} MIPS_ISA(const MIPS_ISA &v) = default; MIPS_ISA
&operator=(const MIPS_ISA &rhs) = default; MIPS_ISA &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const MIPS_ISA &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const MIPS_ISA &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
66
67LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)struct YAMLFlowString { YAMLFlowString() = default; YAMLFlowString
(const StringRef v) : value(v) {} YAMLFlowString(const YAMLFlowString
&v) = default; YAMLFlowString &operator=(const YAMLFlowString
&rhs) = default; YAMLFlowString &operator=(const StringRef
&rhs) { value = rhs; return *this; } operator const StringRef
& () const { return value; } bool operator==(const YAMLFlowString
&rhs) const { return value == rhs.value; } bool operator
==(const StringRef &rhs) const { return value == rhs; } bool
operator<(const YAMLFlowString &rhs) const { return value
< rhs.value; } StringRef value; using BaseType = StringRef
; };
68
69// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
70// since 64-bit can hold 32-bit values too.
71struct FileHeader {
72 ELF_ELFCLASS Class;
73 ELF_ELFDATA Data;
74 ELF_ELFOSABI OSABI;
75 llvm::yaml::Hex8 ABIVersion;
76 ELF_ET Type;
77 ELF_EM Machine;
78 ELF_EF Flags;
79 llvm::yaml::Hex64 Entry;
80
81 Optional<llvm::yaml::Hex16> SHEntSize;
82 Optional<llvm::yaml::Hex64> SHOff;
83 Optional<llvm::yaml::Hex16> SHNum;
84 Optional<llvm::yaml::Hex16> SHStrNdx;
85};
86
87struct SectionName {
88 StringRef Section;
89};
90
91struct ProgramHeader {
92 ELF_PT Type;
93 ELF_PF Flags;
94 llvm::yaml::Hex64 VAddr;
95 llvm::yaml::Hex64 PAddr;
96 Optional<llvm::yaml::Hex64> Align;
97 Optional<llvm::yaml::Hex64> FileSize;
98 Optional<llvm::yaml::Hex64> MemSize;
99 Optional<llvm::yaml::Hex64> Offset;
100 std::vector<SectionName> Sections;
101};
102
103struct Symbol {
104 StringRef Name;
105 Optional<uint32_t> NameIndex;
106 ELF_STT Type;
107 StringRef Section;
108 Optional<ELF_SHN> Index;
109 ELF_STB Binding;
110 llvm::yaml::Hex64 Value;
111 llvm::yaml::Hex64 Size;
112 Optional<uint8_t> Other;
113};
114
115struct SectionOrType {
116 StringRef sectionNameOrType;
117};
118
119struct DynamicEntry {
120 ELF_DYNTAG Tag;
121 llvm::yaml::Hex64 Val;
122};
123
124struct StackSizeEntry {
125 llvm::yaml::Hex64 Address;
126 llvm::yaml::Hex64 Size;
127};
128
129struct NoteEntry {
130 StringRef Name;
131 yaml::BinaryRef Desc;
132 llvm::yaml::Hex32 Type;
133};
134
135struct Chunk {
136 enum class ChunkKind {
137 Dynamic,
138 Group,
139 RawContent,
140 Relocation,
141 NoBits,
142 Note,
143 Hash,
144 GnuHash,
145 Verdef,
146 Verneed,
147 StackSizes,
148 SymtabShndxSection,
149 Symver,
150 MipsABIFlags,
151 Addrsig,
152 Fill,
153 LinkerOptions,
154 DependentLibraries,
155 };
156
157 ChunkKind Kind;
158 StringRef Name;
159
160 Chunk(ChunkKind K) : Kind(K) {}
161 virtual ~Chunk();
162};
163
164struct Section : public Chunk {
165 ELF_SHT Type;
166 Optional<ELF_SHF> Flags;
167 llvm::yaml::Hex64 Address;
168 StringRef Link;
169 llvm::yaml::Hex64 AddressAlign;
170 Optional<llvm::yaml::Hex64> EntSize;
171
172 // Usually sections are not created implicitly, but loaded from YAML.
173 // When they are, this flag is used to signal about that.
174 bool IsImplicit;
175
176 Section(ChunkKind Kind, bool IsImplicit = false)
177 : Chunk(Kind), IsImplicit(IsImplicit) {}
178
179 static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; }
180
181 // The following members are used to override section fields which is
182 // useful for creating invalid objects.
183
184 // This can be used to override the offset stored in the sh_name field.
185 // It does not affect the name stored in the string table.
186 Optional<llvm::yaml::Hex64> ShName;
187
188 // This can be used to override the sh_offset field. It does not place the
189 // section data at the offset specified.
190 Optional<llvm::yaml::Hex64> ShOffset;
191
192 // This can be used to override the sh_size field. It does not affect the
193 // content written.
194 Optional<llvm::yaml::Hex64> ShSize;
195
196 // This can be used to override the sh_flags field.
197 Optional<llvm::yaml::Hex64> ShFlags;
198};
199
200// Fill is a block of data which is placed outside of sections. It is
201// not present in the sections header table, but it might affect the output file
202// size and program headers produced.
203struct Fill : Chunk {
204 Optional<yaml::BinaryRef> Pattern;
205 llvm::yaml::Hex64 Size;
206
207 // We have to remember the offset of the fill, because it does not have
208 // a corresponding section header, unlike a section. We might need this
209 // information when writing the output.
210 uint64_t ShOffset;
211
212 Fill() : Chunk(ChunkKind::Fill) {}
213
214 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
215};
216
217struct StackSizesSection : Section {
218 Optional<yaml::BinaryRef> Content;
219 Optional<llvm::yaml::Hex64> Size;
220 Optional<std::vector<StackSizeEntry>> Entries;
221
222 StackSizesSection() : Section(ChunkKind::StackSizes) {}
223
224 static bool classof(const Chunk *S) {
225 return S->Kind == ChunkKind::StackSizes;
226 }
227
228 static bool nameMatches(StringRef Name) {
229 return Name == ".stack_sizes";
230 }
231};
232
233struct DynamicSection : Section {
234 std::vector<DynamicEntry> Entries;
235 Optional<yaml::BinaryRef> Content;
236
237 DynamicSection() : Section(ChunkKind::Dynamic) {}
238
239 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
240};
241
242struct RawContentSection : Section {
243 Optional<yaml::BinaryRef> Content;
244 Optional<llvm::yaml::Hex64> Size;
245 Optional<llvm::yaml::Hex64> Info;
246
247 RawContentSection() : Section(ChunkKind::RawContent) {}
248
249 static bool classof(const Chunk *S) {
250 return S->Kind == ChunkKind::RawContent;
251 }
252};
253
254struct NoBitsSection : Section {
255 llvm::yaml::Hex64 Size;
256
257 NoBitsSection() : Section(ChunkKind::NoBits) {}
258
259 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
260};
261
262struct NoteSection : Section {
263 Optional<yaml::BinaryRef> Content;
264 Optional<llvm::yaml::Hex64> Size;
265 Optional<std::vector<ELFYAML::NoteEntry>> Notes;
266
267 NoteSection() : Section(ChunkKind::Note) {}
268
269 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
270};
271
272struct HashSection : Section {
273 Optional<yaml::BinaryRef> Content;
274 Optional<llvm::yaml::Hex64> Size;
275 Optional<std::vector<uint32_t>> Bucket;
276 Optional<std::vector<uint32_t>> Chain;
277
278 HashSection() : Section(ChunkKind::Hash) {}
279
280 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
281};
282
283struct GnuHashHeader {
284 // The number of hash buckets.
285 // Not used when dumping the object, but can be used to override
286 // the real number of buckets when emiting an object from a YAML document.
287 Optional<llvm::yaml::Hex32> NBuckets;
288
289 // Index of the first symbol in the dynamic symbol table
290 // included in the hash table.
291 llvm::yaml::Hex32 SymNdx;
292
293 // The number of words in the Bloom filter.
294 // Not used when dumping the object, but can be used to override the real
295 // number of words in the Bloom filter when emiting an object from a YAML
296 // document.
297 Optional<llvm::yaml::Hex32> MaskWords;
298
299 // A shift constant used by the Bloom filter.
300 llvm::yaml::Hex32 Shift2;
301};
302
303struct GnuHashSection : Section {
304 Optional<yaml::BinaryRef> Content;
305
306 Optional<GnuHashHeader> Header;
307 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
308 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
309 Optional<std::vector<llvm::yaml::Hex32>> HashValues;
310
311 GnuHashSection() : Section(ChunkKind::GnuHash) {}
312
313 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
314};
315
316struct VernauxEntry {
317 uint32_t Hash;
318 uint16_t Flags;
319 uint16_t Other;
320 StringRef Name;
321};
322
323struct VerneedEntry {
324 uint16_t Version;
325 StringRef File;
326 std::vector<VernauxEntry> AuxV;
327};
328
329struct VerneedSection : Section {
330 Optional<yaml::BinaryRef> Content;
331 Optional<std::vector<VerneedEntry>> VerneedV;
332 llvm::yaml::Hex64 Info;
333
334 VerneedSection() : Section(ChunkKind::Verneed) {}
335
336 static bool classof(const Chunk *S) {
337 return S->Kind == ChunkKind::Verneed;
338 }
339};
340
341struct AddrsigSymbol {
342 AddrsigSymbol(StringRef N) : Name(N), Index(None) {}
343 AddrsigSymbol(llvm::yaml::Hex32 Ndx) : Name(None), Index(Ndx) {}
344 AddrsigSymbol() : Name(None), Index(None) {}
345
346 Optional<StringRef> Name;
347 Optional<llvm::yaml::Hex32> Index;
348};
349
350struct AddrsigSection : Section {
351 Optional<yaml::BinaryRef> Content;
352 Optional<llvm::yaml::Hex64> Size;
353 Optional<std::vector<AddrsigSymbol>> Symbols;
354
355 AddrsigSection() : Section(ChunkKind::Addrsig) {}
356
357 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
358};
359
360struct LinkerOption {
361 StringRef Key;
362 StringRef Value;
363};
364
365struct LinkerOptionsSection : Section {
366 Optional<std::vector<LinkerOption>> Options;
367 Optional<yaml::BinaryRef> Content;
368
369 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
370
371 static bool classof(const Chunk *S) {
372 return S->Kind == ChunkKind::LinkerOptions;
373 }
374};
375
376struct DependentLibrariesSection : Section {
377 Optional<std::vector<YAMLFlowString>> Libs;
378 Optional<yaml::BinaryRef> Content;
379
380 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
381
382 static bool classof(const Chunk *S) {
383 return S->Kind == ChunkKind::DependentLibraries;
384 }
385};
386
387struct SymverSection : Section {
388 std::vector<uint16_t> Entries;
389
390 SymverSection() : Section(ChunkKind::Symver) {}
391
392 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
393};
394
395struct VerdefEntry {
396 uint16_t Version;
397 uint16_t Flags;
398 uint16_t VersionNdx;
399 uint32_t Hash;
400 std::vector<StringRef> VerNames;
401};
402
403struct VerdefSection : Section {
404 Optional<std::vector<VerdefEntry>> Entries;
405 Optional<yaml::BinaryRef> Content;
406
407 llvm::yaml::Hex64 Info;
408
409 VerdefSection() : Section(ChunkKind::Verdef) {}
410
411 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
412};
413
414struct Group : Section {
415 // Members of a group contain a flag and a list of section indices
416 // that are part of the group.
417 std::vector<SectionOrType> Members;
418 Optional<StringRef> Signature; /* Info */
419
420 Group() : Section(ChunkKind::Group) {}
421
422 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
423};
424
425struct Relocation {
426 llvm::yaml::Hex64 Offset;
427 int64_t Addend;
428 ELF_REL Type;
429 Optional<StringRef> Symbol;
430};
431
432struct RelocationSection : Section {
433 std::vector<Relocation> Relocations;
434 StringRef RelocatableSec; /* Info */
435
436 RelocationSection() : Section(ChunkKind::Relocation) {}
437
438 static bool classof(const Chunk *S) {
439 return S->Kind == ChunkKind::Relocation;
440 }
441};
442
443struct SymtabShndxSection : Section {
444 std::vector<uint32_t> Entries;
445
446 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
447
448 static bool classof(const Chunk *S) {
449 return S->Kind == ChunkKind::SymtabShndxSection;
450 }
451};
452
453// Represents .MIPS.abiflags section
454struct MipsABIFlags : Section {
455 llvm::yaml::Hex16 Version;
456 MIPS_ISA ISALevel;
457 llvm::yaml::Hex8 ISARevision;
458 MIPS_AFL_REG GPRSize;
459 MIPS_AFL_REG CPR1Size;
460 MIPS_AFL_REG CPR2Size;
461 MIPS_ABI_FP FpABI;
462 MIPS_AFL_EXT ISAExtension;
463 MIPS_AFL_ASE ASEs;
464 MIPS_AFL_FLAGS1 Flags1;
465 llvm::yaml::Hex32 Flags2;
466
467 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
468
469 static bool classof(const Chunk *S) {
470 return S->Kind == ChunkKind::MipsABIFlags;
471 }
472};
473
474struct Object {
475 FileHeader Header;
476 std::vector<ProgramHeader> ProgramHeaders;
477
478 // An object might contain output section descriptions as well as
479 // custom data that does not belong to any section.
480 std::vector<std::unique_ptr<Chunk>> Chunks;
481
482 // Although in reality the symbols reside in a section, it is a lot
483 // cleaner and nicer if we read them from the YAML as a separate
484 // top-level key, which automatically ensures that invariants like there
485 // being a single SHT_SYMTAB section are upheld.
486 Optional<std::vector<Symbol>> Symbols;
487 Optional<std::vector<Symbol>> DynamicSymbols;
488
489 std::vector<Section *> getSections() {
490 std::vector<Section *> Ret;
491 for (const std::unique_ptr<Chunk> &Sec : Chunks)
492 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
493 Ret.push_back(S);
494 return Ret;
495 }
496};
497
498} // end namespace ELFYAML
499} // end namespace llvm
500
501LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::AddrsigSymbol)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::AddrsigSymbol>::value && !std::
is_same<llvm::ELFYAML::AddrsigSymbol, std::string>::value
&& !std::is_same<llvm::ELFYAML::AddrsigSymbol, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::AddrsigSymbol> { static const bool flow = false; }; } }
502LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::StackSizeEntry>::value && !std::
is_same<llvm::ELFYAML::StackSizeEntry, std::string>::value
&& !std::is_same<llvm::ELFYAML::StackSizeEntry, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::StackSizeEntry> { static const bool flow = false; }; } }
503LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::DynamicEntry>::value && !std::is_same
<llvm::ELFYAML::DynamicEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::DynamicEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::DynamicEntry> { static const bool flow = false; }; } }
504LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::LinkerOption>::value && !std::is_same
<llvm::ELFYAML::LinkerOption, std::string>::value &&
!std::is_same<llvm::ELFYAML::LinkerOption, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::LinkerOption> { static const bool flow = false; }; } }
505LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::NoteEntry>::value && !std::is_same
<llvm::ELFYAML::NoteEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::NoteEntry, llvm::StringRef>
::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::NoteEntry> { static const bool flow = false; }; } }
506LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::ProgramHeader>::value && !std::
is_same<llvm::ELFYAML::ProgramHeader, std::string>::value
&& !std::is_same<llvm::ELFYAML::ProgramHeader, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ProgramHeader> { static const bool flow = false; }; } }
507LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<std::unique_ptr<llvm::ELFYAML::Chunk> >::value &&
!std::is_same<std::unique_ptr<llvm::ELFYAML::Chunk>
, std::string>::value && !std::is_same<std::unique_ptr
<llvm::ELFYAML::Chunk>, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<std::unique_ptr
<llvm::ELFYAML::Chunk> > { static const bool flow = false
; }; } }
508LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::Symbol>::value && !std::is_same
<llvm::ELFYAML::Symbol, std::string>::value && !
std::is_same<llvm::ELFYAML::Symbol, llvm::StringRef>::value
, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Symbol> { static const bool flow = false; }; } }
509LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VerdefEntry>::value && !std::is_same
<llvm::ELFYAML::VerdefEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VerdefEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerdefEntry> { static const bool flow = false; }; } }
510LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VernauxEntry>::value && !std::is_same
<llvm::ELFYAML::VernauxEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VernauxEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VernauxEntry> { static const bool flow = false; }; } }
511LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VerneedEntry>::value && !std::is_same
<llvm::ELFYAML::VerneedEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VerneedEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerneedEntry> { static const bool flow = false; }; } }
512LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::Relocation>::value && !std::is_same
<llvm::ELFYAML::Relocation, std::string>::value &&
!std::is_same<llvm::ELFYAML::Relocation, llvm::StringRef>
::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Relocation> { static const bool flow = false; }; } }
513LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::SectionOrType>::value && !std::
is_same<llvm::ELFYAML::SectionOrType, std::string>::value
&& !std::is_same<llvm::ELFYAML::SectionOrType, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionOrType> { static const bool flow = false; }; } }
514LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::SectionName>::value && !std::is_same
<llvm::ELFYAML::SectionName, std::string>::value &&
!std::is_same<llvm::ELFYAML::SectionName, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionName> { static const bool flow = false; }; } }
515
516namespace llvm {
517namespace yaml {
518
519template <>
520struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
521 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
522};
523
524template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
525 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
526};
527
528template <>
529struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
530 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
531};
532
533template <>
534struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
535 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
536};
537
538template <>
539struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
540 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
541};
542
543template <>
544struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
545 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
546};
547
548template <>
549struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
550 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
551};
552
553template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
554 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
555};
556
557template <>
558struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
559 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
560};
561
562template <>
563struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
564 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
565};
566
567template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
568 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
569};
570
571template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
572 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
573};
574
575template <>
576struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
577 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
578};
579
580template <>
581struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
582 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
583};
584
585template <>
586struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
587 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
588};
589
590template <>
591struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
592 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
593};
594
595template <>
596struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
597 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
598};
599
600template <>
601struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
602 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
603};
604
605template <>
606struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
607 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
608};
609
610template <>
611struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
612 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
613};
614
615template <>
616struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
617 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
618};
619
620template <>
621struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
622 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
623};
624
625template <>
626struct MappingTraits<ELFYAML::FileHeader> {
627 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
628};
629
630template <> struct MappingTraits<ELFYAML::ProgramHeader> {
631 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
632};
633
634template <>
635struct MappingTraits<ELFYAML::Symbol> {
636 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
637 static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
638};
639
640template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
641 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
642};
643
644template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
645 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
646};
647
648template <> struct MappingTraits<ELFYAML::DynamicEntry> {
649 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
650};
651
652template <> struct MappingTraits<ELFYAML::NoteEntry> {
653 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
654};
655
656template <> struct MappingTraits<ELFYAML::VerdefEntry> {
657 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
658};
659
660template <> struct MappingTraits<ELFYAML::VerneedEntry> {
661 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
662};
663
664template <> struct MappingTraits<ELFYAML::VernauxEntry> {
665 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
666};
667
668template <> struct MappingTraits<ELFYAML::AddrsigSymbol> {
669 static void mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym);
670};
671
672template <> struct MappingTraits<ELFYAML::LinkerOption> {
673 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
674};
675
676template <> struct MappingTraits<ELFYAML::Relocation> {
677 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
678};
679
680template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
681 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
682 static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
683};
684
685template <>
686struct MappingTraits<ELFYAML::Object> {
687 static void mapping(IO &IO, ELFYAML::Object &Object);
688};
689
690template <> struct MappingTraits<ELFYAML::SectionOrType> {
691 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
692};
693
694template <> struct MappingTraits<ELFYAML::SectionName> {
695 static void mapping(IO &IO, ELFYAML::SectionName &sectionName);
696};
697
698} // end namespace yaml
699} // end namespace llvm
700
701#endif // LLVM_OBJECTYAML_ELFYAML_H

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/Support/YAMLTraits.h

1//===- llvm/Support/YAMLTraits.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_SUPPORT_YAMLTRAITS_H
10#define LLVM_SUPPORT_YAMLTRAITS_H
11
12#include "llvm/ADT/Optional.h"
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/StringExtras.h"
15#include "llvm/ADT/StringMap.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/ADT/Twine.h"
18#include "llvm/Support/AlignOf.h"
19#include "llvm/Support/Allocator.h"
20#include "llvm/Support/Endian.h"
21#include "llvm/Support/Regex.h"
22#include "llvm/Support/SourceMgr.h"
23#include "llvm/Support/YAMLParser.h"
24#include "llvm/Support/raw_ostream.h"
25#include <cassert>
26#include <cctype>
27#include <cstddef>
28#include <cstdint>
29#include <iterator>
30#include <map>
31#include <memory>
32#include <new>
33#include <string>
34#include <system_error>
35#include <type_traits>
36#include <vector>
37
38namespace llvm {
39namespace yaml {
40
41enum class NodeKind : uint8_t {
42 Scalar,
43 Map,
44 Sequence,
45};
46
47struct EmptyContext {};
48
49/// This class should be specialized by any type that needs to be converted
50/// to/from a YAML mapping. For example:
51///
52/// struct MappingTraits<MyStruct> {
53/// static void mapping(IO &io, MyStruct &s) {
54/// io.mapRequired("name", s.name);
55/// io.mapRequired("size", s.size);
56/// io.mapOptional("age", s.age);
57/// }
58/// };
59template<class T>
60struct MappingTraits {
61 // Must provide:
62 // static void mapping(IO &io, T &fields);
63 // Optionally may provide:
64 // static StringRef validate(IO &io, T &fields);
65 //
66 // The optional flow flag will cause generated YAML to use a flow mapping
67 // (e.g. { a: 0, b: 1 }):
68 // static const bool flow = true;
69};
70
71/// This class is similar to MappingTraits<T> but allows you to pass in
72/// additional context for each map operation. For example:
73///
74/// struct MappingContextTraits<MyStruct, MyContext> {
75/// static void mapping(IO &io, MyStruct &s, MyContext &c) {
76/// io.mapRequired("name", s.name);
77/// io.mapRequired("size", s.size);
78/// io.mapOptional("age", s.age);
79/// ++c.TimesMapped;
80/// }
81/// };
82template <class T, class Context> struct MappingContextTraits {
83 // Must provide:
84 // static void mapping(IO &io, T &fields, Context &Ctx);
85 // Optionally may provide:
86 // static StringRef validate(IO &io, T &fields, Context &Ctx);
87 //
88 // The optional flow flag will cause generated YAML to use a flow mapping
89 // (e.g. { a: 0, b: 1 }):
90 // static const bool flow = true;
91};
92
93/// This class should be specialized by any integral type that converts
94/// to/from a YAML scalar where there is a one-to-one mapping between
95/// in-memory values and a string in YAML. For example:
96///
97/// struct ScalarEnumerationTraits<Colors> {
98/// static void enumeration(IO &io, Colors &value) {
99/// io.enumCase(value, "red", cRed);
100/// io.enumCase(value, "blue", cBlue);
101/// io.enumCase(value, "green", cGreen);
102/// }
103/// };
104template <typename T, typename Enable = void> struct ScalarEnumerationTraits {
105 // Must provide:
106 // static void enumeration(IO &io, T &value);
107};
108
109/// This class should be specialized by any integer type that is a union
110/// of bit values and the YAML representation is a flow sequence of
111/// strings. For example:
112///
113/// struct ScalarBitSetTraits<MyFlags> {
114/// static void bitset(IO &io, MyFlags &value) {
115/// io.bitSetCase(value, "big", flagBig);
116/// io.bitSetCase(value, "flat", flagFlat);
117/// io.bitSetCase(value, "round", flagRound);
118/// }
119/// };
120template <typename T, typename Enable = void> struct ScalarBitSetTraits {
121 // Must provide:
122 // static void bitset(IO &io, T &value);
123};
124
125/// Describe which type of quotes should be used when quoting is necessary.
126/// Some non-printable characters need to be double-quoted, while some others
127/// are fine with simple-quoting, and some don't need any quoting.
128enum class QuotingType { None, Single, Double };
129
130/// This class should be specialized by type that requires custom conversion
131/// to/from a yaml scalar. For example:
132///
133/// template<>
134/// struct ScalarTraits<MyType> {
135/// static void output(const MyType &val, void*, llvm::raw_ostream &out) {
136/// // stream out custom formatting
137/// out << llvm::format("%x", val);
138/// }
139/// static StringRef input(StringRef scalar, void*, MyType &value) {
140/// // parse scalar and set `value`
141/// // return empty string on success, or error string
142/// return StringRef();
143/// }
144/// static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
145/// };
146template <typename T, typename Enable = void> struct ScalarTraits {
147 // Must provide:
148 //
149 // Function to write the value as a string:
150 // static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
151 //
152 // Function to convert a string to a value. Returns the empty
153 // StringRef on success or an error string if string is malformed:
154 // static StringRef input(StringRef scalar, void *ctxt, T &value);
155 //
156 // Function to determine if the value should be quoted.
157 // static QuotingType mustQuote(StringRef);
158};
159
160/// This class should be specialized by type that requires custom conversion
161/// to/from a YAML literal block scalar. For example:
162///
163/// template <>
164/// struct BlockScalarTraits<MyType> {
165/// static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
166/// {
167/// // stream out custom formatting
168/// Out << Value;
169/// }
170/// static StringRef input(StringRef Scalar, void*, MyType &Value) {
171/// // parse scalar and set `value`
172/// // return empty string on success, or error string
173/// return StringRef();
174/// }
175/// };
176template <typename T>
177struct BlockScalarTraits {
178 // Must provide:
179 //
180 // Function to write the value as a string:
181 // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
182 //
183 // Function to convert a string to a value. Returns the empty
184 // StringRef on success or an error string if string is malformed:
185 // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
186 //
187 // Optional:
188 // static StringRef inputTag(T &Val, std::string Tag)
189 // static void outputTag(const T &Val, raw_ostream &Out)
190};
191
192/// This class should be specialized by type that requires custom conversion
193/// to/from a YAML scalar with optional tags. For example:
194///
195/// template <>
196/// struct TaggedScalarTraits<MyType> {
197/// static void output(const MyType &Value, void*, llvm::raw_ostream
198/// &ScalarOut, llvm::raw_ostream &TagOut)
199/// {
200/// // stream out custom formatting including optional Tag
201/// Out << Value;
202/// }
203/// static StringRef input(StringRef Scalar, StringRef Tag, void*, MyType
204/// &Value) {
205/// // parse scalar and set `value`
206/// // return empty string on success, or error string
207/// return StringRef();
208/// }
209/// static QuotingType mustQuote(const MyType &Value, StringRef) {
210/// return QuotingType::Single;
211/// }
212/// };
213template <typename T> struct TaggedScalarTraits {
214 // Must provide:
215 //
216 // Function to write the value and tag as strings:
217 // static void output(const T &Value, void *ctx, llvm::raw_ostream &ScalarOut,
218 // llvm::raw_ostream &TagOut);
219 //
220 // Function to convert a string to a value. Returns the empty
221 // StringRef on success or an error string if string is malformed:
222 // static StringRef input(StringRef Scalar, StringRef Tag, void *ctxt, T
223 // &Value);
224 //
225 // Function to determine if the value should be quoted.
226 // static QuotingType mustQuote(const T &Value, StringRef Scalar);
227};
228
229/// This class should be specialized by any type that needs to be converted
230/// to/from a YAML sequence. For example:
231///
232/// template<>
233/// struct SequenceTraits<MyContainer> {
234/// static size_t size(IO &io, MyContainer &seq) {
235/// return seq.size();
236/// }
237/// static MyType& element(IO &, MyContainer &seq, size_t index) {
238/// if ( index >= seq.size() )
239/// seq.resize(index+1);
240/// return seq[index];
241/// }
242/// };
243template<typename T, typename EnableIf = void>
244struct SequenceTraits {
245 // Must provide:
246 // static size_t size(IO &io, T &seq);
247 // static T::value_type& element(IO &io, T &seq, size_t index);
248 //
249 // The following is option and will cause generated YAML to use
250 // a flow sequence (e.g. [a,b,c]).
251 // static const bool flow = true;
252};
253
254/// This class should be specialized by any type for which vectors of that
255/// type need to be converted to/from a YAML sequence.
256template<typename T, typename EnableIf = void>
257struct SequenceElementTraits {
258 // Must provide:
259 // static const bool flow;
260};
261
262/// This class should be specialized by any type that needs to be converted
263/// to/from a list of YAML documents.
264template<typename T>
265struct DocumentListTraits {
266 // Must provide:
267 // static size_t size(IO &io, T &seq);
268 // static T::value_type& element(IO &io, T &seq, size_t index);
269};
270
271/// This class should be specialized by any type that needs to be converted
272/// to/from a YAML mapping in the case where the names of the keys are not known
273/// in advance, e.g. a string map.
274template <typename T>
275struct CustomMappingTraits {
276 // static void inputOne(IO &io, StringRef key, T &elem);
277 // static void output(IO &io, T &elem);
278};
279
280/// This class should be specialized by any type that can be represented as
281/// a scalar, map, or sequence, decided dynamically. For example:
282///
283/// typedef std::unique_ptr<MyBase> MyPoly;
284///
285/// template<>
286/// struct PolymorphicTraits<MyPoly> {
287/// static NodeKind getKind(const MyPoly &poly) {
288/// return poly->getKind();
289/// }
290/// static MyScalar& getAsScalar(MyPoly &poly) {
291/// if (!poly || !isa<MyScalar>(poly))
292/// poly.reset(new MyScalar());
293/// return *cast<MyScalar>(poly.get());
294/// }
295/// // ...
296/// };
297template <typename T> struct PolymorphicTraits {
298 // Must provide:
299 // static NodeKind getKind(const T &poly);
300 // static scalar_type &getAsScalar(T &poly);
301 // static map_type &getAsMap(T &poly);
302 // static sequence_type &getAsSequence(T &poly);
303};
304
305// Only used for better diagnostics of missing traits
306template <typename T>
307struct MissingTrait;
308
309// Test if ScalarEnumerationTraits<T> is defined on type T.
310template <class T>
311struct has_ScalarEnumerationTraits
312{
313 using Signature_enumeration = void (*)(class IO&, T&);
314
315 template <typename U>
316 static char test(SameType<Signature_enumeration, &U::enumeration>*);
317
318 template <typename U>
319 static double test(...);
320
321 static bool const value =
322 (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
323};
324
325// Test if ScalarBitSetTraits<T> is defined on type T.
326template <class T>
327struct has_ScalarBitSetTraits
328{
329 using Signature_bitset = void (*)(class IO&, T&);
330
331 template <typename U>
332 static char test(SameType<Signature_bitset, &U::bitset>*);
333
334 template <typename U>
335 static double test(...);
336
337 static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
338};
339
340// Test if ScalarTraits<T> is defined on type T.
341template <class T>
342struct has_ScalarTraits
343{
344 using Signature_input = StringRef (*)(StringRef, void*, T&);
345 using Signature_output = void (*)(const T&, void*, raw_ostream&);
346 using Signature_mustQuote = QuotingType (*)(StringRef);
347
348 template <typename U>
349 static char test(SameType<Signature_input, &U::input> *,
350 SameType<Signature_output, &U::output> *,
351 SameType<Signature_mustQuote, &U::mustQuote> *);
352
353 template <typename U>
354 static double test(...);
355
356 static bool const value =
357 (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
358};
359
360// Test if BlockScalarTraits<T> is defined on type T.
361template <class T>
362struct has_BlockScalarTraits
363{
364 using Signature_input = StringRef (*)(StringRef, void *, T &);
365 using Signature_output = void (*)(const T &, void *, raw_ostream &);
366
367 template <typename U>
368 static char test(SameType<Signature_input, &U::input> *,
369 SameType<Signature_output, &U::output> *);
370
371 template <typename U>
372 static double test(...);
373
374 static bool const value =
375 (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
376};
377
378// Test if TaggedScalarTraits<T> is defined on type T.
379template <class T> struct has_TaggedScalarTraits {
380 using Signature_input = StringRef (*)(StringRef, StringRef, void *, T &);
381 using Signature_output = void (*)(const T &, void *, raw_ostream &,
382 raw_ostream &);
383 using Signature_mustQuote = QuotingType (*)(const T &, StringRef);
384
385 template <typename U>
386 static char test(SameType<Signature_input, &U::input> *,
387 SameType<Signature_output, &U::output> *,
388 SameType<Signature_mustQuote, &U::mustQuote> *);
389
390 template <typename U> static double test(...);
391
392 static bool const value =
393 (sizeof(test<TaggedScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
394};
395
396// Test if MappingContextTraits<T> is defined on type T.
397template <class T, class Context> struct has_MappingTraits {
398 using Signature_mapping = void (*)(class IO &, T &, Context &);
399
400 template <typename U>
401 static char test(SameType<Signature_mapping, &U::mapping>*);
402
403 template <typename U>
404 static double test(...);
405
406 static bool const value =
407 (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
408};
409
410// Test if MappingTraits<T> is defined on type T.
411template <class T> struct has_MappingTraits<T, EmptyContext> {
412 using Signature_mapping = void (*)(class IO &, T &);
413
414 template <typename U>
415 static char test(SameType<Signature_mapping, &U::mapping> *);
416
417 template <typename U> static double test(...);
418
419 static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
420};
421
422// Test if MappingContextTraits<T>::validate() is defined on type T.
423template <class T, class Context> struct has_MappingValidateTraits {
424 using Signature_validate = StringRef (*)(class IO &, T &, Context &);
425
426 template <typename U>
427 static char test(SameType<Signature_validate, &U::validate>*);
428
429 template <typename U>
430 static double test(...);
431
432 static bool const value =
433 (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
434};
435
436// Test if MappingTraits<T>::validate() is defined on type T.
437template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
438 using Signature_validate = StringRef (*)(class IO &, T &);
439
440 template <typename U>
441 static char test(SameType<Signature_validate, &U::validate> *);
442
443 template <typename U> static double test(...);
444
445 static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
446};
447
448// Test if SequenceTraits<T> is defined on type T.
449template <class T>
450struct has_SequenceMethodTraits
451{
452 using Signature_size = size_t (*)(class IO&, T&);
453
454 template <typename U>
455 static char test(SameType<Signature_size, &U::size>*);
456
457 template <typename U>
458 static double test(...);
459
460 static bool const value = (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
461};
462
463// Test if CustomMappingTraits<T> is defined on type T.
464template <class T>
465struct has_CustomMappingTraits
466{
467 using Signature_input = void (*)(IO &io, StringRef key, T &v);
468
469 template <typename U>
470 static char test(SameType<Signature_input, &U::inputOne>*);
471
472 template <typename U>
473 static double test(...);
474
475 static bool const value =
476 (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
477};
478
479// has_FlowTraits<int> will cause an error with some compilers because
480// it subclasses int. Using this wrapper only instantiates the
481// real has_FlowTraits only if the template type is a class.
482template <typename T, bool Enabled = std::is_class<T>::value>
483class has_FlowTraits
484{
485public:
486 static const bool value = false;
487};
488
489// Some older gcc compilers don't support straight forward tests
490// for members, so test for ambiguity cause by the base and derived
491// classes both defining the member.
492template <class T>
493struct has_FlowTraits<T, true>
494{
495 struct Fallback { bool flow; };
496 struct Derived : T, Fallback { };
497
498 template<typename C>
499 static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
500
501 template<typename C>
502 static char (&f(...))[2];
503
504 static bool const value = sizeof(f<Derived>(nullptr)) == 2;
505};
506
507// Test if SequenceTraits<T> is defined on type T
508template<typename T>
509struct has_SequenceTraits : public std::integral_constant<bool,
510 has_SequenceMethodTraits<T>::value > { };
511
512// Test if DocumentListTraits<T> is defined on type T
513template <class T>
514struct has_DocumentListTraits
515{
516 using Signature_size = size_t (*)(class IO &, T &);
517
518 template <typename U>
519 static char test(SameType<Signature_size, &U::size>*);
520
521 template <typename U>
522 static double test(...);
523
524 static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
525};
526
527template <class T> struct has_PolymorphicTraits {
528 using Signature_getKind = NodeKind (*)(const T &);
529
530 template <typename U>
531 static char test(SameType<Signature_getKind, &U::getKind> *);
532
533 template <typename U> static double test(...);
534
535 static bool const value = (sizeof(test<PolymorphicTraits<T>>(nullptr)) == 1);
536};
537
538inline bool isNumeric(StringRef S) {
539 const static auto skipDigits = [](StringRef Input) {
540 return Input.drop_front(
541 std::min(Input.find_first_not_of("0123456789"), Input.size()));
542 };
543
544 // Make S.front() and S.drop_front().front() (if S.front() is [+-]) calls
545 // safe.
546 if (S.empty() || S.equals("+") || S.equals("-"))
547 return false;
548
549 if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
550 return true;
551
552 // Infinity and decimal numbers can be prefixed with sign.
553 StringRef Tail = (S.front() == '-' || S.front() == '+') ? S.drop_front() : S;
554
555 // Check for infinity first, because checking for hex and oct numbers is more
556 // expensive.
557 if (Tail.equals(".inf") || Tail.equals(".Inf") || Tail.equals(".INF"))
558 return true;
559
560 // Section 10.3.2 Tag Resolution
561 // YAML 1.2 Specification prohibits Base 8 and Base 16 numbers prefixed with
562 // [-+], so S should be used instead of Tail.
563 if (S.startswith("0o"))
564 return S.size() > 2 &&
565 S.drop_front(2).find_first_not_of("01234567") == StringRef::npos;
566
567 if (S.startswith("0x"))
568 return S.size() > 2 && S.drop_front(2).find_first_not_of(
569 "0123456789abcdefABCDEF") == StringRef::npos;
570
571 // Parse float: [-+]? (\. [0-9]+ | [0-9]+ (\. [0-9]* )?) ([eE] [-+]? [0-9]+)?
572 S = Tail;
573
574 // Handle cases when the number starts with '.' and hence needs at least one
575 // digit after dot (as opposed by number which has digits before the dot), but
576 // doesn't have one.
577 if (S.startswith(".") &&
578 (S.equals(".") ||
579 (S.size() > 1 && std::strchr("0123456789", S[1]) == nullptr)))
580 return false;
581
582 if (S.startswith("E") || S.startswith("e"))
583 return false;
584
585 enum ParseState {
586 Default,
587 FoundDot,
588 FoundExponent,
589 };
590 ParseState State = Default;
591
592 S = skipDigits(S);
593
594 // Accept decimal integer.
595 if (S.empty())
596 return true;
597
598 if (S.front() == '.') {
599 State = FoundDot;
600 S = S.drop_front();
601 } else if (S.front() == 'e' || S.front() == 'E') {
602 State = FoundExponent;
603 S = S.drop_front();
604 } else {
605 return false;
606 }
607
608 if (State == FoundDot) {
609 S = skipDigits(S);
610 if (S.empty())
611 return true;
612
613 if (S.front() == 'e' || S.front() == 'E') {
614 State = FoundExponent;
615 S = S.drop_front();
616 } else {
617 return false;
618 }
619 }
620
621 assert(State == FoundExponent && "Should have found exponent at this point.")((State == FoundExponent && "Should have found exponent at this point."
) ? static_cast<void> (0) : __assert_fail ("State == FoundExponent && \"Should have found exponent at this point.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/Support/YAMLTraits.h"
, 621, __PRETTY_FUNCTION__))
;
622 if (S.empty())
623 return false;
624
625 if (S.front() == '+' || S.front() == '-') {
626 S = S.drop_front();
627 if (S.empty())
628 return false;
629 }
630
631 return skipDigits(S).empty();
632}
633
634inline bool isNull(StringRef S) {
635 return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
636 S.equals("~");
637}
638
639inline bool isBool(StringRef S) {
640 return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
641 S.equals("false") || S.equals("False") || S.equals("FALSE");
642}
643
644// 5.1. Character Set
645// The allowed character range explicitly excludes the C0 control block #x0-#x1F
646// (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
647// control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
648// block #xD800-#xDFFF, #xFFFE, and #xFFFF.
649inline QuotingType needsQuotes(StringRef S) {
650 if (S.empty())
651 return QuotingType::Single;
652 if (isspace(static_cast<unsigned char>(S.front())) ||
653 isspace(static_cast<unsigned char>(S.back())))
654 return QuotingType::Single;
655 if (isNull(S))
656 return QuotingType::Single;
657 if (isBool(S))
658 return QuotingType::Single;
659 if (isNumeric(S))
660 return QuotingType::Single;
661
662 // 7.3.3 Plain Style
663 // Plain scalars must not begin with most indicators, as this would cause
664 // ambiguity with other YAML constructs.
665 static constexpr char Indicators[] = R"(-?:\,[]{}#&*!|>'"%@`)";
666 if (S.find_first_of(Indicators) == 0)
667 return QuotingType::Single;
668
669 QuotingType MaxQuotingNeeded = QuotingType::None;
670 for (unsigned char C : S) {
671 // Alphanum is safe.
672 if (isAlnum(C))
673 continue;
674
675 switch (C) {
676 // Safe scalar characters.
677 case '_':
678 case '-':
679 case '^':
680 case '.':
681 case ',':
682 case ' ':
683 // TAB (0x9) is allowed in unquoted strings.
684 case 0x9:
685 continue;
686 // LF(0xA) and CR(0xD) may delimit values and so require at least single
687 // quotes.
688 case 0xA:
689 case 0xD:
690 MaxQuotingNeeded = QuotingType::Single;
691 continue;
692 // DEL (0x7F) are excluded from the allowed character range.
693 case 0x7F:
694 return QuotingType::Double;
695 // Forward slash is allowed to be unquoted, but we quote it anyway. We have
696 // many tests that use FileCheck against YAML output, and this output often
697 // contains paths. If we quote backslashes but not forward slashes then
698 // paths will come out either quoted or unquoted depending on which platform
699 // the test is run on, making FileCheck comparisons difficult.
700 case '/':
701 default: {
702 // C0 control block (0x0 - 0x1F) is excluded from the allowed character
703 // range.
704 if (C <= 0x1F)
705 return QuotingType::Double;
706
707 // Always double quote UTF-8.
708 if ((C & 0x80) != 0)
709 return QuotingType::Double;
710
711 // The character is not safe, at least simple quoting needed.
712 MaxQuotingNeeded = QuotingType::Single;
713 }
714 }
715 }
716
717 return MaxQuotingNeeded;
718}
719
720template <typename T, typename Context>
721struct missingTraits
722 : public std::integral_constant<bool,
723 !has_ScalarEnumerationTraits<T>::value &&
724 !has_ScalarBitSetTraits<T>::value &&
725 !has_ScalarTraits<T>::value &&
726 !has_BlockScalarTraits<T>::value &&
727 !has_TaggedScalarTraits<T>::value &&
728 !has_MappingTraits<T, Context>::value &&
729 !has_SequenceTraits<T>::value &&
730 !has_CustomMappingTraits<T>::value &&
731 !has_DocumentListTraits<T>::value &&
732 !has_PolymorphicTraits<T>::value> {};
733
734template <typename T, typename Context>
735struct validatedMappingTraits
736 : public std::integral_constant<
737 bool, has_MappingTraits<T, Context>::value &&
738 has_MappingValidateTraits<T, Context>::value> {};
739
740template <typename T, typename Context>
741struct unvalidatedMappingTraits
742 : public std::integral_constant<
743 bool, has_MappingTraits<T, Context>::value &&
744 !has_MappingValidateTraits<T, Context>::value> {};
745
746// Base class for Input and Output.
747class IO {
748public:
749 IO(void *Ctxt = nullptr);
750 virtual ~IO();
751
752 virtual bool outputting() const = 0;
753
754 virtual unsigned beginSequence() = 0;
755 virtual bool preflightElement(unsigned, void *&) = 0;
756 virtual void postflightElement(void*) = 0;
757 virtual void endSequence() = 0;
758 virtual bool canElideEmptySequence() = 0;
759
760 virtual unsigned beginFlowSequence() = 0;
761 virtual bool preflightFlowElement(unsigned, void *&) = 0;
762 virtual void postflightFlowElement(void*) = 0;
763 virtual void endFlowSequence() = 0;
764
765 virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
766 virtual void beginMapping() = 0;
767 virtual void endMapping() = 0;
768 virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
769 virtual void postflightKey(void*) = 0;
770 virtual std::vector<StringRef> keys() = 0;
771
772 virtual void beginFlowMapping() = 0;
773 virtual void endFlowMapping() = 0;
774
775 virtual void beginEnumScalar() = 0;
776 virtual bool matchEnumScalar(const char*, bool) = 0;
777 virtual bool matchEnumFallback() = 0;
778 virtual void endEnumScalar() = 0;
779
780 virtual bool beginBitSetScalar(bool &) = 0;
781 virtual bool bitSetMatch(const char*, bool) = 0;
782 virtual void endBitSetScalar() = 0;
783
784 virtual void scalarString(StringRef &, QuotingType) = 0;
785 virtual void blockScalarString(StringRef &) = 0;
786 virtual void scalarTag(std::string &) = 0;
787
788 virtual NodeKind getNodeKind() = 0;
789
790 virtual void setError(const Twine &) = 0;
791
792 template <typename T>
793 void enumCase(T &Val, const char* Str, const T ConstVal) {
794 if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
795 Val = ConstVal;
796 }
797 }
798
799 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
800 template <typename T>
801 void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
802 if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
17
Assuming the condition is false
18
Assuming the condition is false
19
Taking false branch
23
Assuming the condition is false
24
Assuming the condition is false
25
Taking false branch
29
Assuming the condition is false
30
Assuming the condition is false
31
Taking false branch
35
Assuming the condition is false
36
Assuming the condition is false
37
Taking false branch
41
Assuming the condition is false
42
Assuming the condition is false
43
Taking false branch
47
Assuming the condition is false
48
Assuming the condition is false
49
Taking false branch
53
Assuming the condition is false
54
Assuming the condition is false
55
Taking false branch
59
Assuming the condition is false
60
Assuming the condition is false
61
Taking false branch
65
Assuming the condition is false
66
Assuming the condition is false
67
Taking false branch
71
Assuming the condition is false
72
Assuming the condition is false
73
Taking false branch
77
Assuming the condition is false
78
Assuming the condition is false
79
Taking false branch
83
Assuming the condition is false
84
Assuming the condition is false
85
Taking false branch
89
Assuming the condition is false
90
Assuming the condition is false
91
Taking false branch
95
Assuming the condition is false
96
Assuming the condition is false
97
Taking false branch
101
Assuming the condition is false
102
Assuming the condition is false
103
Taking false branch
107
Assuming the condition is false
108
Assuming the condition is false
109
Taking false branch
113
Assuming the condition is false
114
Assuming the condition is false
115
Taking false branch
119
Assuming the condition is false
120
Assuming the condition is false
121
Taking false branch
125
Assuming the condition is false
126
Assuming the condition is false
127
Taking false branch
131
Assuming the condition is false
132
Assuming the condition is false
133
Taking false branch
137
Assuming the condition is false
138
Assuming the condition is false
139
Taking false branch
143
Assuming the condition is false
144
Assuming the condition is false
145
Taking false branch
149
Assuming the condition is false
150
Assuming the condition is false
151
Taking false branch
155
Assuming the condition is false
156
Assuming the condition is false
157
Taking false branch
161
Assuming the condition is false
162
Assuming the condition is false
163
Taking false branch
167
Assuming the condition is false
168
Assuming the condition is false
169
Taking false branch
173
Assuming the condition is false
174
Assuming the condition is false
175
Taking false branch
179
Assuming the condition is false
180
Assuming the condition is false
181
Taking false branch
185
Assuming the condition is false
186
Assuming the condition is false
187
Taking false branch
191
Assuming the condition is false
192
Assuming the condition is false
193
Taking false branch
197
Assuming the condition is false
198
Assuming the condition is false
199
Taking false branch
203
Assuming the condition is false
204
Assuming the condition is false
205
Taking false branch
209
Assuming the condition is false
210
Assuming the condition is false
211
Taking false branch
215
Assuming the condition is false
216
Assuming the condition is false
217
Taking false branch
803 Val = ConstVal;
804 }
805 }
20
Returning without writing to 'Val.value'
26
Returning without writing to 'Val.value'
32
Returning without writing to 'Val.value'
38
Returning without writing to 'Val.value'
44
Returning without writing to 'Val.value'
50
Returning without writing to 'Val.value'
56
Returning without writing to 'Val.value'
62
Returning without writing to 'Val.value'
68
Returning without writing to 'Val.value'
74
Returning without writing to 'Val.value'
80
Returning without writing to 'Val.value'
86
Returning without writing to 'Val.value'
92
Returning without writing to 'Val.value'
98
Returning without writing to 'Val.value'
104
Returning without writing to 'Val.value'
110
Returning without writing to 'Val.value'
116
Returning without writing to 'Val.value'
122
Returning without writing to 'Val.value'
128
Returning without writing to 'Val.value'
134
Returning without writing to 'Val.value'
140
Returning without writing to 'Val.value'
146
Returning without writing to 'Val.value'
152
Returning without writing to 'Val.value'
158
Returning without writing to 'Val.value'
164
Returning without writing to 'Val.value'
170
Returning without writing to 'Val.value'
176
Returning without writing to 'Val.value'
182
Returning without writing to 'Val.value'
188
Returning without writing to 'Val.value'
194
Returning without writing to 'Val.value'
200
Returning without writing to 'Val.value'
206
Returning without writing to 'Val.value'
212
Returning without writing to 'Val.value'
218
Returning without writing to 'Val.value'
806
807 template <typename FBT, typename T>
808 void enumFallback(T &Val) {
809 if (matchEnumFallback()) {
223
Assuming the condition is true
224
Taking true branch
810 EmptyContext Context;
811 // FIXME: Force integral conversion to allow strong typedefs to convert.
812 FBT Res = static_cast<typename FBT::BaseType>(Val);
225
1st function call argument is an uninitialized value
813 yamlize(*this, Res, true, Context);
814 Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
815 }
816 }
817
818 template <typename T>
819 void bitSetCase(T &Val, const char* Str, const T ConstVal) {
820 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
821 Val = static_cast<T>(Val | ConstVal);
822 }
823 }
824
825 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
826 template <typename T>
827 void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
828 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
829 Val = static_cast<T>(Val | ConstVal);
830 }
831 }
832
833 template <typename T>
834 void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
835 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
836 Val = Val | ConstVal;
837 }
838
839 template <typename T>
840 void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
841 uint32_t Mask) {
842 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
843 Val = Val | ConstVal;
844 }
845
846 void *getContext() const;
847 void setContext(void *);
848
849 template <typename T> void mapRequired(const char *Key, T &Val) {
850 EmptyContext Ctx;
851 this->processKey(Key, Val, true, Ctx);
9
Calling 'IO::processKey'
852 }
853
854 template <typename T, typename Context>
855 void mapRequired(const char *Key, T &Val, Context &Ctx) {
856 this->processKey(Key, Val, true, Ctx);
857 }
858
859 template <typename T> void mapOptional(const char *Key, T &Val) {
860 EmptyContext Ctx;
861 mapOptionalWithContext(Key, Val, Ctx);
862 }
863
864 template <typename T, typename DefaultT>
865 void mapOptional(const char *Key, T &Val, const DefaultT &Default) {
866 EmptyContext Ctx;
867 mapOptionalWithContext(Key, Val, Default, Ctx);
868 }
869
870 template <typename T, typename Context>
871 typename std::enable_if<has_SequenceTraits<T>::value, void>::type
872 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
873 // omit key/value instead of outputting empty sequence
874 if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
875 return;
876 this->processKey(Key, Val, false, Ctx);
877 }
878
879 template <typename T, typename Context>
880 void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
881 this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
882 Ctx);
883 }
884
885 template <typename T, typename Context>
886 typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
887 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
888 this->processKey(Key, Val, false, Ctx);
889 }
890
891 template <typename T, typename Context, typename DefaultT>
892 void mapOptionalWithContext(const char *Key, T &Val, const DefaultT &Default,
893 Context &Ctx) {
894 static_assert(std::is_convertible<DefaultT, T>::value,
895 "Default type must be implicitly convertible to value type!");
896 this->processKeyWithDefault(Key, Val, static_cast<const T &>(Default),
897 false, Ctx);
898 }
899
900private:
901 template <typename T, typename Context>
902 void processKeyWithDefault(const char *Key, Optional<T> &Val,
903 const Optional<T> &DefaultValue, bool Required,
904 Context &Ctx) {
905 assert(DefaultValue.hasValue() == false &&((DefaultValue.hasValue() == false && "Optional<T> shouldn't have a value!"
) ? static_cast<void> (0) : __assert_fail ("DefaultValue.hasValue() == false && \"Optional<T> shouldn't have a value!\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/Support/YAMLTraits.h"
, 906, __PRETTY_FUNCTION__))
906 "Optional<T> shouldn't have a value!")((DefaultValue.hasValue() == false && "Optional<T> shouldn't have a value!"
) ? static_cast<void> (0) : __assert_fail ("DefaultValue.hasValue() == false && \"Optional<T> shouldn't have a value!\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/Support/YAMLTraits.h"
, 906, __PRETTY_FUNCTION__))
;
907 void *SaveInfo;
908 bool UseDefault = true;
909 const bool sameAsDefault = outputting() && !Val.hasValue();
910 if (!outputting() && !Val.hasValue())
911 Val = T();
912 if (Val.hasValue() &&
913 this->preflightKey(Key, Required, sameAsDefault, UseDefault,
914 SaveInfo)) {
915 yamlize(*this, Val.getValue(), Required, Ctx);
916 this->postflightKey(SaveInfo);
917 } else {
918 if (UseDefault)
919 Val = DefaultValue;
920 }
921 }
922
923 template <typename T, typename Context>
924 void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
925 bool Required, Context &Ctx) {
926 void *SaveInfo;
927 bool UseDefault;
928 const bool sameAsDefault = outputting() && Val == DefaultValue;
929 if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
930 SaveInfo) ) {
931 yamlize(*this, Val, Required, Ctx);
932 this->postflightKey(SaveInfo);
933 }
934 else {
935 if ( UseDefault )
936 Val = DefaultValue;
937 }
938 }
939
940 template <typename T, typename Context>
941 void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
942 void *SaveInfo;
943 bool UseDefault;
944 if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
10
Assuming the condition is true
11
Taking true branch
945 yamlize(*this, Val, Required, Ctx);
12
Calling 'yamlize<llvm::ELFYAML::ELF_SHT>'
946 this->postflightKey(SaveInfo);
947 }
948 }
949
950private:
951 void *Ctxt;
952};
953
954namespace detail {
955
956template <typename T, typename Context>
957void doMapping(IO &io, T &Val, Context &Ctx) {
958 MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
959}
960
961template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
962 MappingTraits<T>::mapping(io, Val);
963}
964
965} // end namespace detail
966
967template <typename T>
968typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
969yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
970 io.beginEnumScalar();
971 ScalarEnumerationTraits<T>::enumeration(io, Val);
13
Calling 'ScalarEnumerationTraits::enumeration'
972 io.endEnumScalar();
973}
974
975template <typename T>
976typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
977yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
978 bool DoClear;
979 if ( io.beginBitSetScalar(DoClear) ) {
980 if ( DoClear )
981 Val = T();
982 ScalarBitSetTraits<T>::bitset(io, Val);
983 io.endBitSetScalar();
984 }
985}
986
987template <typename T>
988typename std::enable_if<has_ScalarTraits<T>::value, void>::type
989yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
990 if ( io.outputting() ) {
991 std::string Storage;
992 raw_string_ostream Buffer(Storage);
993 ScalarTraits<T>::output(Val, io.getContext(), Buffer);
994 StringRef Str = Buffer.str();
995 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
996 }
997 else {
998 StringRef Str;
999 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1000 StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
1001 if ( !Result.empty() ) {
1002 io.setError(Twine(Result));
1003 }
1004 }
1005}
1006
1007template <typename T>
1008typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
1009yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
1010 if (YamlIO.outputting()) {
1011 std::string Storage;
1012 raw_string_ostream Buffer(Storage);
1013 BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
1014 StringRef Str = Buffer.str();
1015 YamlIO.blockScalarString(Str);
1016 } else {
1017 StringRef Str;
1018 YamlIO.blockScalarString(Str);
1019 StringRef Result =
1020 BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
1021 if (!Result.empty())
1022 YamlIO.setError(Twine(Result));
1023 }
1024}
1025
1026template <typename T>
1027typename std::enable_if<has_TaggedScalarTraits<T>::value, void>::type
1028yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1029 if (io.outputting()) {
1030 std::string ScalarStorage, TagStorage;
1031 raw_string_ostream ScalarBuffer(ScalarStorage), TagBuffer(TagStorage);
1032 TaggedScalarTraits<T>::output(Val, io.getContext(), ScalarBuffer,
1033 TagBuffer);
1034 io.scalarTag(TagBuffer.str());
1035 StringRef ScalarStr = ScalarBuffer.str();
1036 io.scalarString(ScalarStr,
1037 TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
1038 } else {
1039 std::string Tag;
1040 io.scalarTag(Tag);
1041 StringRef Str;
1042 io.scalarString(Str, QuotingType::None);
1043 StringRef Result =
1044 TaggedScalarTraits<T>::input(Str, Tag, io.getContext(), Val);
1045 if (!Result.empty()) {
1046 io.setError(Twine(Result));
1047 }
1048 }
1049}
1050
1051template <typename T, typename Context>
1052typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
1053yamlize(IO &io, T &Val, bool, Context &Ctx) {
1054 if (has_FlowTraits<MappingTraits<T>>::value)
1055 io.beginFlowMapping();
1056 else
1057 io.beginMapping();
1058 if (io.outputting()) {
1059 StringRef Err = MappingTraits<T>::validate(io, Val);
1060 if (!Err.empty()) {
1061 errs() << Err << "\n";
1062 assert(Err.empty() && "invalid struct trying to be written as yaml")((Err.empty() && "invalid struct trying to be written as yaml"
) ? static_cast<void> (0) : __assert_fail ("Err.empty() && \"invalid struct trying to be written as yaml\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/Support/YAMLTraits.h"
, 1062, __PRETTY_FUNCTION__))
;
1063 }
1064 }
1065 detail::doMapping(io, Val, Ctx);
1066 if (!io.outputting()) {
1067 StringRef Err = MappingTraits<T>::validate(io, Val);
1068 if (!Err.empty())
1069 io.setError(Err);
1070 }
1071 if (has_FlowTraits<MappingTraits<T>>::value)
1072 io.endFlowMapping();
1073 else
1074 io.endMapping();
1075}
1076
1077template <typename T, typename Context>
1078typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
1079yamlize(IO &io, T &Val, bool, Context &Ctx) {
1080 if (has_FlowTraits<MappingTraits<T>>::value) {
1081 io.beginFlowMapping();
1082 detail::doMapping(io, Val, Ctx);
1083 io.endFlowMapping();
1084 } else {
1085 io.beginMapping();
1086 detail::doMapping(io, Val, Ctx);
1087 io.endMapping();
1088 }
1089}
1090
1091template <typename T>
1092typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
1093yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1094 if ( io.outputting() ) {
1095 io.beginMapping();
1096 CustomMappingTraits<T>::output(io, Val);
1097 io.endMapping();
1098 } else {
1099 io.beginMapping();
1100 for (StringRef key : io.keys())
1101 CustomMappingTraits<T>::inputOne(io, key, Val);
1102 io.endMapping();
1103 }
1104}
1105
1106template <typename T>
1107typename std::enable_if<has_PolymorphicTraits<T>::value, void>::type
1108yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1109 switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
1110 : io.getNodeKind()) {
1111 case NodeKind::Scalar:
1112 return yamlize(io, PolymorphicTraits<T>::getAsScalar(Val), true, Ctx);
1113 case NodeKind::Map:
1114 return yamlize(io, PolymorphicTraits<T>::getAsMap(Val), true, Ctx);
1115 case NodeKind::Sequence:
1116 return yamlize(io, PolymorphicTraits<T>::getAsSequence(Val), true, Ctx);
1117 }
1118}
1119
1120template <typename T>
1121typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
1122yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1123 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1124}
1125
1126template <typename T, typename Context>
1127typename std::enable_if<has_SequenceTraits<T>::value, void>::type
1128yamlize(IO &io, T &Seq, bool, Context &Ctx) {
1129 if ( has_FlowTraits< SequenceTraits<T>>::value ) {
1130 unsigned incnt = io.beginFlowSequence();
1131 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1132 for(unsigned i=0; i < count; ++i) {
1133 void *SaveInfo;
1134 if ( io.preflightFlowElement(i, SaveInfo) ) {
1135 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1136 io.postflightFlowElement(SaveInfo);
1137 }
1138 }
1139 io.endFlowSequence();
1140 }
1141 else {
1142 unsigned incnt = io.beginSequence();
1143 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1144 for(unsigned i=0; i < count; ++i) {
1145 void *SaveInfo;
1146 if ( io.preflightElement(i, SaveInfo) ) {
1147 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1148 io.postflightElement(SaveInfo);
1149 }
1150 }
1151 io.endSequence();
1152 }
1153}
1154
1155template<>
1156struct ScalarTraits<bool> {
1157 static void output(const bool &, void* , raw_ostream &);
1158 static StringRef input(StringRef, void *, bool &);
1159 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1160};
1161
1162template<>
1163struct ScalarTraits<StringRef> {
1164 static void output(const StringRef &, void *, raw_ostream &);
1165 static StringRef input(StringRef, void *, StringRef &);
1166 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1167};
1168
1169template<>
1170struct ScalarTraits<std::string> {
1171 static void output(const std::string &, void *, raw_ostream &);
1172 static StringRef input(StringRef, void *, std::string &);
1173 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1174};
1175
1176template<>
1177struct ScalarTraits<uint8_t> {
1178 static void output(const uint8_t &, void *, raw_ostream &);
1179 static StringRef input(StringRef, void *, uint8_t &);
1180 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1181};
1182
1183template<>
1184struct ScalarTraits<uint16_t> {
1185 static void output(const uint16_t &, void *, raw_ostream &);
1186 static StringRef input(StringRef, void *, uint16_t &);
1187 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1188};
1189
1190template<>
1191struct ScalarTraits<uint32_t> {
1192 static void output(const uint32_t &, void *, raw_ostream &);
1193 static StringRef input(StringRef, void *, uint32_t &);
1194 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1195};
1196
1197template<>
1198struct ScalarTraits<uint64_t> {
1199 static void output(const uint64_t &, void *, raw_ostream &);
1200 static StringRef input(StringRef, void *, uint64_t &);
1201 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1202};
1203
1204template<>
1205struct ScalarTraits<int8_t> {
1206 static void output(const int8_t &, void *, raw_ostream &);
1207 static StringRef input(StringRef, void *, int8_t &);
1208 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1209};
1210
1211template<>
1212struct ScalarTraits<int16_t> {
1213 static void output(const int16_t &, void *, raw_ostream &);
1214 static StringRef input(StringRef, void *, int16_t &);
1215 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1216};
1217
1218template<>
1219struct ScalarTraits<int32_t> {
1220 static void output(const int32_t &, void *, raw_ostream &);
1221 static StringRef input(StringRef, void *, int32_t &);
1222 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1223};
1224
1225template<>
1226struct ScalarTraits<int64_t> {
1227 static void output(const int64_t &, void *, raw_ostream &);
1228 static StringRef input(StringRef, void *, int64_t &);
1229 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1230};
1231
1232template<>
1233struct ScalarTraits<float> {
1234 static void output(const float &, void *, raw_ostream &);
1235 static StringRef input(StringRef, void *, float &);
1236 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1237};
1238
1239template<>
1240struct ScalarTraits<double> {
1241 static void output(const double &, void *, raw_ostream &);
1242 static StringRef input(StringRef, void *, double &);
1243 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1244};
1245
1246// For endian types, we use existing scalar Traits class for the underlying
1247// type. This way endian aware types are supported whenever the traits are
1248// defined for the underlying type.
1249template <typename value_type, support::endianness endian, size_t alignment>
1250struct ScalarTraits<
1251 support::detail::packed_endian_specific_integral<value_type, endian,
1252 alignment>,
1253 typename std::enable_if<has_ScalarTraits<value_type>::value>::type> {
1254 using endian_type =
1255 support::detail::packed_endian_specific_integral<value_type, endian,
1256 alignment>;
1257
1258 static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1259 ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1260 }
1261
1262 static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1263 value_type V;
1264 auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1265 E = static_cast<endian_type>(V);
1266 return R;
1267 }
1268
1269 static QuotingType mustQuote(StringRef Str) {
1270 return ScalarTraits<value_type>::mustQuote(Str);
1271 }
1272};
1273
1274template <typename value_type, support::endianness endian, size_t alignment>
1275struct ScalarEnumerationTraits<
1276 support::detail::packed_endian_specific_integral<value_type, endian,
1277 alignment>,
1278 typename std::enable_if<
1279 has_ScalarEnumerationTraits<value_type>::value>::type> {
1280 using endian_type =
1281 support::detail::packed_endian_specific_integral<value_type, endian,
1282 alignment>;
1283
1284 static void enumeration(IO &io, endian_type &E) {
1285 value_type V = E;
1286 ScalarEnumerationTraits<value_type>::enumeration(io, V);
1287 E = V;
1288 }
1289};
1290
1291template <typename value_type, support::endianness endian, size_t alignment>
1292struct ScalarBitSetTraits<
1293 support::detail::packed_endian_specific_integral<value_type, endian,
1294 alignment>,
1295 typename std::enable_if<has_ScalarBitSetTraits<value_type>::value>::type> {
1296 using endian_type =
1297 support::detail::packed_endian_specific_integral<value_type, endian,
1298 alignment>;
1299 static void bitset(IO &io, endian_type &E) {
1300 value_type V = E;
1301 ScalarBitSetTraits<value_type>::bitset(io, V);
1302 E = V;
1303 }
1304};
1305
1306// Utility for use within MappingTraits<>::mapping() method
1307// to [de]normalize an object for use with YAML conversion.
1308template <typename TNorm, typename TFinal>
1309struct MappingNormalization {
1310 MappingNormalization(IO &i_o, TFinal &Obj)
1311 : io(i_o), BufPtr(nullptr), Result(Obj) {
1312 if ( io.outputting() ) {
1313 BufPtr = new (&Buffer) TNorm(io, Obj);
1314 }
1315 else {
1316 BufPtr = new (&Buffer) TNorm(io);
1317 }
1318 }
1319
1320 ~MappingNormalization() {
1321 if ( ! io.outputting() ) {
1322 Result = BufPtr->denormalize(io);
1323 }
1324 BufPtr->~TNorm();
1325 }
1326
1327 TNorm* operator->() { return BufPtr; }
1328
1329private:
1330 using Storage = AlignedCharArrayUnion<TNorm>;
1331
1332 Storage Buffer;
1333 IO &io;
1334 TNorm *BufPtr;
1335 TFinal &Result;
1336};
1337
1338// Utility for use within MappingTraits<>::mapping() method
1339// to [de]normalize an object for use with YAML conversion.
1340template <typename TNorm, typename TFinal>
1341struct MappingNormalizationHeap {
1342 MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1343 : io(i_o), Result(Obj) {
1344 if ( io.outputting() ) {
1345 BufPtr = new (&Buffer) TNorm(io, Obj);
1346 }
1347 else if (allocator) {
1348 BufPtr = allocator->Allocate<TNorm>();
1349 new (BufPtr) TNorm(io);
1350 } else {
1351 BufPtr = new TNorm(io);
1352 }
1353 }
1354
1355 ~MappingNormalizationHeap() {
1356 if ( io.outputting() ) {
1357 BufPtr->~TNorm();
1358 }
1359 else {
1360 Result = BufPtr->denormalize(io);
1361 }
1362 }
1363
1364 TNorm* operator->() { return BufPtr; }
1365
1366private:
1367 using Storage = AlignedCharArrayUnion<TNorm>;
1368
1369 Storage Buffer;
1370 IO &io;
1371 TNorm *BufPtr = nullptr;
1372 TFinal &Result;
1373};
1374
1375///
1376/// The Input class is used to parse a yaml document into in-memory structs
1377/// and vectors.
1378///
1379/// It works by using YAMLParser to do a syntax parse of the entire yaml
1380/// document, then the Input class builds a graph of HNodes which wraps
1381/// each yaml Node. The extra layer is buffering. The low level yaml
1382/// parser only lets you look at each node once. The buffering layer lets
1383/// you search and interate multiple times. This is necessary because
1384/// the mapRequired() method calls may not be in the same order
1385/// as the keys in the document.
1386///
1387class Input : public IO {
1388public:
1389 // Construct a yaml Input object from a StringRef and optional
1390 // user-data. The DiagHandler can be specified to provide
1391 // alternative error reporting.
1392 Input(StringRef InputContent,
1393 void *Ctxt = nullptr,
1394 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1395 void *DiagHandlerCtxt = nullptr);
1396 Input(MemoryBufferRef Input,
1397 void *Ctxt = nullptr,
1398 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1399 void *DiagHandlerCtxt = nullptr);
1400 ~Input() override;
1401
1402 // Check if there was an syntax or semantic error during parsing.
1403 std::error_code error();
1404
1405private:
1406 bool outputting() const override;
1407 bool mapTag(StringRef, bool) override;
1408 void beginMapping() override;
1409 void endMapping() override;
1410 bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1411 void postflightKey(void *) override;
1412 std::vector<StringRef> keys() override;
1413 void beginFlowMapping() override;
1414 void endFlowMapping() override;
1415 unsigned beginSequence() override;
1416 void endSequence() override;
1417 bool preflightElement(unsigned index, void *&) override;
1418 void postflightElement(void *) override;
1419 unsigned beginFlowSequence() override;
1420 bool preflightFlowElement(unsigned , void *&) override;
1421 void postflightFlowElement(void *) override;
1422 void endFlowSequence() override;
1423 void beginEnumScalar() override;
1424 bool matchEnumScalar(const char*, bool) override;
1425 bool matchEnumFallback() override;
1426 void endEnumScalar() override;
1427 bool beginBitSetScalar(bool &) override;
1428 bool bitSetMatch(const char *, bool ) override;
1429 void endBitSetScalar() override;
1430 void scalarString(StringRef &, QuotingType) override;
1431 void blockScalarString(StringRef &) override;
1432 void scalarTag(std::string &) override;
1433 NodeKind getNodeKind() override;
1434 void setError(const Twine &message) override;
1435 bool canElideEmptySequence() override;
1436
1437 class HNode {
1438 virtual void anchor();
1439
1440 public:
1441 HNode(Node *n) : _node(n) { }
1442 virtual ~HNode() = default;
1443
1444 static bool classof(const HNode *) { return true; }
1445
1446 Node *_node;
1447 };
1448
1449 class EmptyHNode : public HNode {
1450 void anchor() override;
1451
1452 public:
1453 EmptyHNode(Node *n) : HNode(n) { }
1454
1455 static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1456
1457 static bool classof(const EmptyHNode *) { return true; }
1458 };
1459
1460 class ScalarHNode : public HNode {
1461 void anchor() override;
1462
1463 public:
1464 ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1465
1466 StringRef value() const { return _value; }
1467
1468 static bool classof(const HNode *n) {
1469 return ScalarNode::classof(n->_node) ||
1470 BlockScalarNode::classof(n->_node);
1471 }
1472
1473 static bool classof(const ScalarHNode *) { return true; }
1474
1475 protected:
1476 StringRef _value;
1477 };
1478
1479 class MapHNode : public HNode {
1480 void anchor() override;
1481
1482 public:
1483 MapHNode(Node *n) : HNode(n) { }
1484
1485 static bool classof(const HNode *n) {
1486 return MappingNode::classof(n->_node);
1487 }
1488
1489 static bool classof(const MapHNode *) { return true; }
1490
1491 using NameToNode = StringMap<std::unique_ptr<HNode>>;
1492
1493 NameToNode Mapping;
1494 SmallVector<std::string, 6> ValidKeys;
1495 };
1496
1497 class SequenceHNode : public HNode {
1498 void anchor() override;
1499
1500 public:
1501 SequenceHNode(Node *n) : HNode(n) { }
1502
1503 static bool classof(const HNode *n) {
1504 return SequenceNode::classof(n->_node);
1505 }
1506
1507 static bool classof(const SequenceHNode *) { return true; }
1508
1509 std::vector<std::unique_ptr<HNode>> Entries;
1510 };
1511
1512 std::unique_ptr<Input::HNode> createHNodes(Node *node);
1513 void setError(HNode *hnode, const Twine &message);
1514 void setError(Node *node, const Twine &message);
1515
1516public:
1517 // These are only used by operator>>. They could be private
1518 // if those templated things could be made friends.
1519 bool setCurrentDocument();
1520 bool nextDocument();
1521
1522 /// Returns the current node that's being parsed by the YAML Parser.
1523 const Node *getCurrentNode() const;
1524
1525private:
1526 SourceMgr SrcMgr; // must be before Strm
1527 std::unique_ptr<llvm::yaml::Stream> Strm;
1528 std::unique_ptr<HNode> TopNode;
1529 std::error_code EC;
1530 BumpPtrAllocator StringAllocator;
1531 document_iterator DocIterator;
1532 std::vector<bool> BitValuesUsed;
1533 HNode *CurrentNode = nullptr;
1534 bool ScalarMatchFound = false;
1535};
1536
1537///
1538/// The Output class is used to generate a yaml document from in-memory structs
1539/// and vectors.
1540///
1541class Output : public IO {
1542public:
1543 Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1544 ~Output() override;
1545
1546 /// Set whether or not to output optional values which are equal
1547 /// to the default value. By default, when outputting if you attempt
1548 /// to write a value that is equal to the default, the value gets ignored.
1549 /// Sometimes, it is useful to be able to see these in the resulting YAML
1550 /// anyway.
1551 void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1552
1553 bool outputting() const override;
1554 bool mapTag(StringRef, bool) override;
1555 void beginMapping() override;
1556 void endMapping() override;
1557 bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1558 void postflightKey(void *) override;
1559 std::vector<StringRef> keys() override;
1560 void beginFlowMapping() override;
1561 void endFlowMapping() override;
1562 unsigned beginSequence() override;
1563 void endSequence() override;
1564 bool preflightElement(unsigned, void *&) override;
1565 void postflightElement(void *) override;
1566 unsigned beginFlowSequence() override;
1567 bool preflightFlowElement(unsigned, void *&) override;
1568 void postflightFlowElement(void *) override;
1569 void endFlowSequence() override;
1570 void beginEnumScalar() override;
1571 bool matchEnumScalar(const char*, bool) override;
1572 bool matchEnumFallback() override;
1573 void endEnumScalar() override;
1574 bool beginBitSetScalar(bool &) override;
1575 bool bitSetMatch(const char *, bool ) override;
1576 void endBitSetScalar() override;
1577 void scalarString(StringRef &, QuotingType) override;
1578 void blockScalarString(StringRef &) override;
1579 void scalarTag(std::string &) override;
1580 NodeKind getNodeKind() override;
1581 void setError(const Twine &message) override;
1582 bool canElideEmptySequence() override;
1583
1584 // These are only used by operator<<. They could be private
1585 // if that templated operator could be made a friend.
1586 void beginDocuments();
1587 bool preflightDocument(unsigned);
1588 void postflightDocument();
1589 void endDocuments();
1590
1591private:
1592 void output(StringRef s);
1593 void outputUpToEndOfLine(StringRef s);
1594 void newLineCheck();
1595 void outputNewLine();
1596 void paddedKey(StringRef key);
1597 void flowKey(StringRef Key);
1598
1599 enum InState {
1600 inSeqFirstElement,
1601 inSeqOtherElement,
1602 inFlowSeqFirstElement,
1603 inFlowSeqOtherElement,
1604 inMapFirstKey,
1605 inMapOtherKey,
1606 inFlowMapFirstKey,
1607 inFlowMapOtherKey
1608 };
1609
1610 static bool inSeqAnyElement(InState State);
1611 static bool inFlowSeqAnyElement(InState State);
1612 static bool inMapAnyKey(InState State);
1613 static bool inFlowMapAnyKey(InState State);
1614
1615 raw_ostream &Out;
1616 int WrapColumn;
1617 SmallVector<InState, 8> StateStack;
1618 int Column = 0;
1619 int ColumnAtFlowStart = 0;
1620 int ColumnAtMapFlowStart = 0;
1621 bool NeedBitValueComma = false;
1622 bool NeedFlowSequenceComma = false;
1623 bool EnumerationMatchFound = false;
1624 bool WriteDefaultValues = false;
1625 StringRef Padding;
1626 StringRef PaddingBeforeContainer;
1627};
1628
1629/// YAML I/O does conversion based on types. But often native data types
1630/// are just a typedef of built in intergral types (e.g. int). But the C++
1631/// type matching system sees through the typedef and all the typedefed types
1632/// look like a built in type. This will cause the generic YAML I/O conversion
1633/// to be used. To provide better control over the YAML conversion, you can
1634/// use this macro instead of typedef. It will create a class with one field
1635/// and automatic conversion operators to and from the base type.
1636/// Based on BOOST_STRONG_TYPEDEF
1637#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)struct _type { _type() = default; _type(const _base v) : value
(v) {} _type(const _type &v) = default; _type &operator
=(const _type &rhs) = default; _type &operator=(const
_base &rhs) { value = rhs; return *this; } operator const
_base & () const { return value; } bool operator==(const
_type &rhs) const { return value == rhs.value; } bool operator
==(const _base &rhs) const { return value == rhs; } bool operator
<(const _type &rhs) const { return value < rhs.value
; } _base value; using BaseType = _base; };
\
1638 struct _type { \
1639 _type() = default; \
1640 _type(const _base v) : value(v) {} \
1641 _type(const _type &v) = default; \
1642 _type &operator=(const _type &rhs) = default; \
1643 _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1644 operator const _base & () const { return value; } \
1645 bool operator==(const _type &rhs) const { return value == rhs.value; } \
1646 bool operator==(const _base &rhs) const { return value == rhs; } \
1647 bool operator<(const _type &rhs) const { return value < rhs.value; } \
1648 _base value; \
1649 using BaseType = _base; \
1650 };
1651
1652///
1653/// Use these types instead of uintXX_t in any mapping to have
1654/// its yaml output formatted as hexadecimal.
1655///
1656LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)struct Hex8 { Hex8() = default; Hex8(const uint8_t v) : value
(v) {} Hex8(const Hex8 &v) = default; Hex8 &operator=
(const Hex8 &rhs) = default; Hex8 &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const Hex8 &
rhs) const { return value == rhs.value; } bool operator==(const
uint8_t &rhs) const { return value == rhs; } bool operator
<(const Hex8 &rhs) const { return value < rhs.value
; } uint8_t value; using BaseType = uint8_t; };
1657LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)struct Hex16 { Hex16() = default; Hex16(const uint16_t v) : value
(v) {} Hex16(const Hex16 &v) = default; Hex16 &operator
=(const Hex16 &rhs) = default; Hex16 &operator=(const
uint16_t &rhs) { value = rhs; return *this; } operator const
uint16_t & () const { return value; } bool operator==(const
Hex16 &rhs) const { return value == rhs.value; } bool operator
==(const uint16_t &rhs) const { return value == rhs; } bool
operator<(const Hex16 &rhs) const { return value <
rhs.value; } uint16_t value; using BaseType = uint16_t; };
1658LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)struct Hex32 { Hex32() = default; Hex32(const uint32_t v) : value
(v) {} Hex32(const Hex32 &v) = default; Hex32 &operator
=(const Hex32 &rhs) = default; Hex32 &operator=(const
uint32_t &rhs) { value = rhs; return *this; } operator const
uint32_t & () const { return value; } bool operator==(const
Hex32 &rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const Hex32 &rhs) const { return value <
rhs.value; } uint32_t value; using BaseType = uint32_t; };
1659LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)struct Hex64 { Hex64() = default; Hex64(const uint64_t v) : value
(v) {} Hex64(const Hex64 &v) = default; Hex64 &operator
=(const Hex64 &rhs) = default; Hex64 &operator=(const
uint64_t &rhs) { value = rhs; return *this; } operator const
uint64_t & () const { return value; } bool operator==(const
Hex64 &rhs) const { return value == rhs.value; } bool operator
==(const uint64_t &rhs) const { return value == rhs; } bool
operator<(const Hex64 &rhs) const { return value <
rhs.value; } uint64_t value; using BaseType = uint64_t; };
1660
1661template<>
1662struct ScalarTraits<Hex8> {
1663 static void output(const Hex8 &, void *, raw_ostream &);
1664 static StringRef input(StringRef, void *, Hex8 &);
1665 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1666};
1667
1668template<>
1669struct ScalarTraits<Hex16> {
1670 static void output(const Hex16 &, void *, raw_ostream &);
1671 static StringRef input(StringRef, void *, Hex16 &);
1672 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1673};
1674
1675template<>
1676struct ScalarTraits<Hex32> {
1677 static void output(const Hex32 &, void *, raw_ostream &);
1678 static StringRef input(StringRef, void *, Hex32 &);
1679 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1680};
1681
1682template<>
1683struct ScalarTraits<Hex64> {
1684 static void output(const Hex64 &, void *, raw_ostream &);
1685 static StringRef input(StringRef, void *, Hex64 &);
1686 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1687};
1688
1689// Define non-member operator>> so that Input can stream in a document list.
1690template <typename T>
1691inline
1692typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1693operator>>(Input &yin, T &docList) {
1694 int i = 0;
1695 EmptyContext Ctx;
1696 while ( yin.setCurrentDocument() ) {
1697 yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1698 if ( yin.error() )
1699 return yin;
1700 yin.nextDocument();
1701 ++i;
1702 }
1703 return yin;
1704}
1705
1706// Define non-member operator>> so that Input can stream in a map as a document.
1707template <typename T>
1708inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1709 Input &>::type
1710operator>>(Input &yin, T &docMap) {
1711 EmptyContext Ctx;
1712 yin.setCurrentDocument();
1713 yamlize(yin, docMap, true, Ctx);
1714 return yin;
1715}
1716
1717// Define non-member operator>> so that Input can stream in a sequence as
1718// a document.
1719template <typename T>
1720inline
1721typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1722operator>>(Input &yin, T &docSeq) {
1723 EmptyContext Ctx;
1724 if (yin.setCurrentDocument())
1725 yamlize(yin, docSeq, true, Ctx);
1726 return yin;
1727}
1728
1729// Define non-member operator>> so that Input can stream in a block scalar.
1730template <typename T>
1731inline
1732typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1733operator>>(Input &In, T &Val) {
1734 EmptyContext Ctx;
1735 if (In.setCurrentDocument())
1736 yamlize(In, Val, true, Ctx);
1737 return In;
1738}
1739
1740// Define non-member operator>> so that Input can stream in a string map.
1741template <typename T>
1742inline
1743typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
1744operator>>(Input &In, T &Val) {
1745 EmptyContext Ctx;
1746 if (In.setCurrentDocument())
1747 yamlize(In, Val, true, Ctx);
1748 return In;
1749}
1750
1751// Define non-member operator>> so that Input can stream in a polymorphic type.
1752template <typename T>
1753inline typename std::enable_if<has_PolymorphicTraits<T>::value, Input &>::type
1754operator>>(Input &In, T &Val) {
1755 EmptyContext Ctx;
1756 if (In.setCurrentDocument())
1757 yamlize(In, Val, true, Ctx);
1758 return In;
1759}
1760
1761// Provide better error message about types missing a trait specialization
1762template <typename T>
1763inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1764 Input &>::type
1765operator>>(Input &yin, T &docSeq) {
1766 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1767 return yin;
1768}
1769
1770// Define non-member operator<< so that Output can stream out document list.
1771template <typename T>
1772inline
1773typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1774operator<<(Output &yout, T &docList) {
1775 EmptyContext Ctx;
1776 yout.beginDocuments();
1777 const size_t count = DocumentListTraits<T>::size(yout, docList);
1778 for(size_t i=0; i < count; ++i) {
1779 if ( yout.preflightDocument(i) ) {
1780 yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1781 Ctx);
1782 yout.postflightDocument();
1783 }
1784 }
1785 yout.endDocuments();
1786 return yout;
1787}
1788
1789// Define non-member operator<< so that Output can stream out a map.
1790template <typename T>
1791inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1792 Output &>::type
1793operator<<(Output &yout, T &map) {
1794 EmptyContext Ctx;
1795 yout.beginDocuments();
1796 if ( yout.preflightDocument(0) ) {
1797 yamlize(yout, map, true, Ctx);
1798 yout.postflightDocument();
1799 }
1800 yout.endDocuments();
1801 return yout;
1802}
1803
1804// Define non-member operator<< so that Output can stream out a sequence.
1805template <typename T>
1806inline
1807typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1808operator<<(Output &yout, T &seq) {
1809 EmptyContext Ctx;
1810 yout.beginDocuments();
1811 if ( yout.preflightDocument(0) ) {
1812 yamlize(yout, seq, true, Ctx);
1813 yout.postflightDocument();
1814 }
1815 yout.endDocuments();
1816 return yout;
1817}
1818
1819// Define non-member operator<< so that Output can stream out a block scalar.
1820template <typename T>
1821inline
1822typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1823operator<<(Output &Out, T &Val) {
1824 EmptyContext Ctx;
1825 Out.beginDocuments();
1826 if (Out.preflightDocument(0)) {
1827 yamlize(Out, Val, true, Ctx);
1828 Out.postflightDocument();
1829 }
1830 Out.endDocuments();
1831 return Out;
1832}
1833
1834// Define non-member operator<< so that Output can stream out a string map.
1835template <typename T>
1836inline
1837typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
1838operator<<(Output &Out, T &Val) {
1839 EmptyContext Ctx;
1840 Out.beginDocuments();
1841 if (Out.preflightDocument(0)) {
1842 yamlize(Out, Val, true, Ctx);
1843 Out.postflightDocument();
1844 }
1845 Out.endDocuments();
1846 return Out;
1847}
1848
1849// Define non-member operator<< so that Output can stream out a polymorphic
1850// type.
1851template <typename T>
1852inline typename std::enable_if<has_PolymorphicTraits<T>::value, Output &>::type
1853operator<<(Output &Out, T &Val) {
1854 EmptyContext Ctx;
1855 Out.beginDocuments();
1856 if (Out.preflightDocument(0)) {
1857 // FIXME: The parser does not support explicit documents terminated with a
1858 // plain scalar; the end-marker is included as part of the scalar token.
1859 assert(PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && "plain scalar documents are not supported")((PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar
&& "plain scalar documents are not supported") ? static_cast
<void> (0) : __assert_fail ("PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && \"plain scalar documents are not supported\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/Support/YAMLTraits.h"
, 1859, __PRETTY_FUNCTION__))
;
1860 yamlize(Out, Val, true, Ctx);
1861 Out.postflightDocument();
1862 }
1863 Out.endDocuments();
1864 return Out;
1865}
1866
1867// Provide better error message about types missing a trait specialization
1868template <typename T>
1869inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1870 Output &>::type
1871operator<<(Output &yout, T &seq) {
1872 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1873 return yout;
1874}
1875
1876template <bool B> struct IsFlowSequenceBase {};
1877template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1878
1879template <typename T, bool Flow>
1880struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1881private:
1882 using type = typename T::value_type;
1883
1884public:
1885 static size_t size(IO &io, T &seq) { return seq.size(); }
1886
1887 static type &element(IO &io, T &seq, size_t index) {
1888 if (index >= seq.size())
1889 seq.resize(index + 1);
1890 return seq[index];
1891 }
1892};
1893
1894// Simple helper to check an expression can be used as a bool-valued template
1895// argument.
1896template <bool> struct CheckIsBool { static const bool value = true; };
1897
1898// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1899// SequenceTraits that do the obvious thing.
1900template <typename T>
1901struct SequenceTraits<std::vector<T>,
1902 typename std::enable_if<CheckIsBool<
1903 SequenceElementTraits<T>::flow>::value>::type>
1904 : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1905template <typename T, unsigned N>
1906struct SequenceTraits<SmallVector<T, N>,
1907 typename std::enable_if<CheckIsBool<
1908 SequenceElementTraits<T>::flow>::value>::type>
1909 : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1910template <typename T>
1911struct SequenceTraits<SmallVectorImpl<T>,
1912 typename std::enable_if<CheckIsBool<
1913 SequenceElementTraits<T>::flow>::value>::type>
1914 : SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
1915
1916// Sequences of fundamental types use flow formatting.
1917template <typename T>
1918struct SequenceElementTraits<
1919 T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
1920 static const bool flow = true;
1921};
1922
1923// Sequences of strings use block formatting.
1924template<> struct SequenceElementTraits<std::string> {
1925 static const bool flow = false;
1926};
1927template<> struct SequenceElementTraits<StringRef> {
1928 static const bool flow = false;
1929};
1930template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1931 static const bool flow = false;
1932};
1933
1934/// Implementation of CustomMappingTraits for std::map<std::string, T>.
1935template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1936 using map_type = std::map<std::string, T>;
1937
1938 static void inputOne(IO &io, StringRef key, map_type &v) {
1939 io.mapRequired(key.str().c_str(), v[key]);
1940 }
1941
1942 static void output(IO &io, map_type &v) {
1943 for (auto &p : v)
1944 io.mapRequired(p.first.c_str(), p.second);
1945 }
1946};
1947
1948} // end namespace yaml
1949} // end namespace llvm
1950
1951#define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<TYPE>::value && !std::is_same<TYPE, std::string
>::value && !std::is_same<TYPE, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<TYPE>
{ static const bool flow = FLOW; }; } }
\
1952 namespace llvm { \
1953 namespace yaml { \
1954 static_assert( \
1955 !std::is_fundamental<TYPE>::value && \
1956 !std::is_same<TYPE, std::string>::value && \
1957 !std::is_same<TYPE, llvm::StringRef>::value, \
1958 "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
1959 template <> struct SequenceElementTraits<TYPE> { \
1960 static const bool flow = FLOW; \
1961 }; \
1962 } \
1963 }
1964
1965/// Utility for declaring that a std::vector of a particular type
1966/// should be considered a YAML sequence.
1967#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = false; }; } }
\
1968 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = false; }; } }
1969
1970/// Utility for declaring that a std::vector of a particular type
1971/// should be considered a YAML flow sequence.
1972#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = true; }; } }
\
1973 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = true; }; } }
1974
1975#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)namespace llvm { namespace yaml { template <> struct MappingTraits
<Type> { static void mapping(IO &IO, Type &Obj)
; }; } }
\
1976 namespace llvm { \
1977 namespace yaml { \
1978 template <> struct MappingTraits<Type> { \
1979 static void mapping(IO &IO, Type &Obj); \
1980 }; \
1981 } \
1982 }
1983
1984#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<Type> { static void enumeration(IO &io, Type &
Value); }; } }
\
1985 namespace llvm { \
1986 namespace yaml { \
1987 template <> struct ScalarEnumerationTraits<Type> { \
1988 static void enumeration(IO &io, Type &Value); \
1989 }; \
1990 } \
1991 }
1992
1993#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<Type> { static void bitset(IO &IO, Type &Options
); }; } }
\
1994 namespace llvm { \
1995 namespace yaml { \
1996 template <> struct ScalarBitSetTraits<Type> { \
1997 static void bitset(IO &IO, Type &Options); \
1998 }; \
1999 } \
2000 }
2001
2002#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)namespace llvm { namespace yaml { template <> struct ScalarTraits
<Type> { static void output(const Type &Value, void
*ctx, raw_ostream &Out); static StringRef input(StringRef
Scalar, void *ctxt, Type &Value); static QuotingType mustQuote
(StringRef) { return MustQuote; } }; } }
\
2003 namespace llvm { \
2004 namespace yaml { \
2005 template <> struct ScalarTraits<Type> { \
2006 static void output(const Type &Value, void *ctx, raw_ostream &Out); \
2007 static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
2008 static QuotingType mustQuote(StringRef) { return MustQuote; } \
2009 }; \
2010 } \
2011 }
2012
2013/// Utility for declaring that a std::vector of a particular type
2014/// should be considered a YAML document list.
2015#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)namespace llvm { namespace yaml { template <unsigned N>
struct DocumentListTraits<SmallVector<_type, N>>
: public SequenceTraitsImpl<SmallVector<_type, N>, false
> {}; template <> struct DocumentListTraits<std::
vector<_type>> : public SequenceTraitsImpl<std::vector
<_type>, false> {}; } }
\
2016 namespace llvm { \
2017 namespace yaml { \
2018 template <unsigned N> \
2019 struct DocumentListTraits<SmallVector<_type, N>> \
2020 : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
2021 template <> \
2022 struct DocumentListTraits<std::vector<_type>> \
2023 : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
2024 } \
2025 }
2026
2027/// Utility for declaring that std::map<std::string, _type> should be considered
2028/// a YAML map.
2029#define LLVM_YAML_IS_STRING_MAP(_type)namespace llvm { namespace yaml { template <> struct CustomMappingTraits
<std::map<std::string, _type>> : public StdMapStringCustomMappingTraitsImpl
<_type> {}; } }
\
2030 namespace llvm { \
2031 namespace yaml { \
2032 template <> \
2033 struct CustomMappingTraits<std::map<std::string, _type>> \
2034 : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
2035 } \
2036 }
2037
2038LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex64>::value && !std::is_same<
llvm::yaml::Hex64, std::string>::value && !std::is_same
<llvm::yaml::Hex64, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex64> { static const bool flow = true; }; } }
2039LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex32)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex32>::value && !std::is_same<
llvm::yaml::Hex32, std::string>::value && !std::is_same
<llvm::yaml::Hex32, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex32> { static const bool flow = true; }; } }
2040LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex16)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex16>::value && !std::is_same<
llvm::yaml::Hex16, std::string>::value && !std::is_same
<llvm::yaml::Hex16, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex16> { static const bool flow = true; }; } }
2041LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex8)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex8>::value && !std::is_same<llvm
::yaml::Hex8, std::string>::value && !std::is_same
<llvm::yaml::Hex8, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex8> { static const bool flow = true; }; } }
2042
2043#endif // LLVM_SUPPORT_YAMLTRAITS_H