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 -fuse-init-array -target-cpu x86-64 -dwarf-column-info -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~+201911111502510600c19528f1809/build-llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/include -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/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~+201911111502510600c19528f1809/build-llvm/lib/ObjectYAML -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809=. -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-2019-12-07-102640-14763-1 -x c++ /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/llvm/lib/ObjectYAML/ELFYAML.cpp

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

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

/build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/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~+201911111502510600c19528f1809/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~+201911111502510600c19528f1809/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~+201911111502510600c19528f1809/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~+201911111502510600c19528f1809/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~+201911111502510600c19528f1809/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