Bug Summary

File:llvm/include/llvm/ObjectYAML/ELFYAML.h
Warning:line 51, column 1
The left operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ELFYAML.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/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-11/lib/clang/11.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-11~++20200309111110+2c36c23f347/build-llvm/lib/ObjectYAML -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ObjectYAML/ELFYAML.cpp

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ObjectYAML/ELFYAML.cpp

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

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

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/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-11~++20200309111110+2c36c23f347/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 true
18
Calling 'ELF_SHT::operator=='
803 Val = ConstVal;
804 }
805 }
806
807 template <typename FBT, typename T>
808 void enumFallback(T &Val) {
809 if (matchEnumFallback()) {
810 EmptyContext Context;
811 // FIXME: Force integral conversion to allow strong typedefs to convert.
812 FBT Res = static_cast<typename FBT::BaseType>(Val);
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 std::enable_if_t<has_SequenceTraits<T>::value, void>
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 std::enable_if_t<!has_SequenceTraits<T>::value, void>
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-11~++20200309111110+2c36c23f347/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-11~++20200309111110+2c36c23f347/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>
968std::enable_if_t<has_ScalarEnumerationTraits<T>::value, void>
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>
976std::enable_if_t<has_ScalarBitSetTraits<T>::value, void>
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>
988std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
989 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>
1008std::enable_if_t<has_BlockScalarTraits<T>::value, void>
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>
1027std::enable_if_t<has_TaggedScalarTraits<T>::value, void>
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>
1052std::enable_if_t<validatedMappingTraits<T, Context>::value, void>
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-11~++20200309111110+2c36c23f347/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>
1078std::enable_if_t<unvalidatedMappingTraits<T, Context>::value, void>
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>
1092std::enable_if_t<has_CustomMappingTraits<T>::value, void>
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>
1107std::enable_if_t<has_PolymorphicTraits<T>::value, void>
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>
1121std::enable_if_t<missingTraits<T, EmptyContext>::value, void>
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>
1127std::enable_if_t<has_SequenceTraits<T>::value, void>
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<support::detail::packed_endian_specific_integral<
1251 value_type, endian, alignment>,
1252 std::enable_if_t<has_ScalarTraits<value_type>::value>> {
1253 using endian_type =
1254 support::detail::packed_endian_specific_integral<value_type, endian,
1255 alignment>;
1256
1257 static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1258 ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1259 }
1260
1261 static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1262 value_type V;
1263 auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1264 E = static_cast<endian_type>(V);
1265 return R;
1266 }
1267
1268 static QuotingType mustQuote(StringRef Str) {
1269 return ScalarTraits<value_type>::mustQuote(Str);
1270 }
1271};
1272
1273template <typename value_type, support::endianness endian, size_t alignment>
1274struct ScalarEnumerationTraits<
1275 support::detail::packed_endian_specific_integral<value_type, endian,
1276 alignment>,
1277 std::enable_if_t<has_ScalarEnumerationTraits<value_type>::value>> {
1278 using endian_type =
1279 support::detail::packed_endian_specific_integral<value_type, endian,
1280 alignment>;
1281
1282 static void enumeration(IO &io, endian_type &E) {
1283 value_type V = E;
1284 ScalarEnumerationTraits<value_type>::enumeration(io, V);
1285 E = V;
1286 }
1287};
1288
1289template <typename value_type, support::endianness endian, size_t alignment>
1290struct ScalarBitSetTraits<
1291 support::detail::packed_endian_specific_integral<value_type, endian,
1292 alignment>,
1293 std::enable_if_t<has_ScalarBitSetTraits<value_type>::value>> {
1294 using endian_type =
1295 support::detail::packed_endian_specific_integral<value_type, endian,
1296 alignment>;
1297 static void bitset(IO &io, endian_type &E) {
1298 value_type V = E;
1299 ScalarBitSetTraits<value_type>::bitset(io, V);
1300 E = V;
1301 }
1302};
1303
1304// Utility for use within MappingTraits<>::mapping() method
1305// to [de]normalize an object for use with YAML conversion.
1306template <typename TNorm, typename TFinal>
1307struct MappingNormalization {
1308 MappingNormalization(IO &i_o, TFinal &Obj)
1309 : io(i_o), BufPtr(nullptr), Result(Obj) {
1310 if ( io.outputting() ) {
1311 BufPtr = new (&Buffer) TNorm(io, Obj);
1312 }
1313 else {
1314 BufPtr = new (&Buffer) TNorm(io);
1315 }
1316 }
1317
1318 ~MappingNormalization() {
1319 if ( ! io.outputting() ) {
1320 Result = BufPtr->denormalize(io);
1321 }
1322 BufPtr->~TNorm();
1323 }
1324
1325 TNorm* operator->() { return BufPtr; }
1326
1327private:
1328 using Storage = AlignedCharArrayUnion<TNorm>;
1329
1330 Storage Buffer;
1331 IO &io;
1332 TNorm *BufPtr;
1333 TFinal &Result;
1334};
1335
1336// Utility for use within MappingTraits<>::mapping() method
1337// to [de]normalize an object for use with YAML conversion.
1338template <typename TNorm, typename TFinal>
1339struct MappingNormalizationHeap {
1340 MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1341 : io(i_o), Result(Obj) {
1342 if ( io.outputting() ) {
1343 BufPtr = new (&Buffer) TNorm(io, Obj);
1344 }
1345 else if (allocator) {
1346 BufPtr = allocator->Allocate<TNorm>();
1347 new (BufPtr) TNorm(io);
1348 } else {
1349 BufPtr = new TNorm(io);
1350 }
1351 }
1352
1353 ~MappingNormalizationHeap() {
1354 if ( io.outputting() ) {
1355 BufPtr->~TNorm();
1356 }
1357 else {
1358 Result = BufPtr->denormalize(io);
1359 }
1360 }
1361
1362 TNorm* operator->() { return BufPtr; }
1363
1364private:
1365 using Storage = AlignedCharArrayUnion<TNorm>;
1366
1367 Storage Buffer;
1368 IO &io;
1369 TNorm *BufPtr = nullptr;
1370 TFinal &Result;
1371};
1372
1373///
1374/// The Input class is used to parse a yaml document into in-memory structs
1375/// and vectors.
1376///
1377/// It works by using YAMLParser to do a syntax parse of the entire yaml
1378/// document, then the Input class builds a graph of HNodes which wraps
1379/// each yaml Node. The extra layer is buffering. The low level yaml
1380/// parser only lets you look at each node once. The buffering layer lets
1381/// you search and interate multiple times. This is necessary because
1382/// the mapRequired() method calls may not be in the same order
1383/// as the keys in the document.
1384///
1385class Input : public IO {
1386public:
1387 // Construct a yaml Input object from a StringRef and optional
1388 // user-data. The DiagHandler can be specified to provide
1389 // alternative error reporting.
1390 Input(StringRef InputContent,
1391 void *Ctxt = nullptr,
1392 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1393 void *DiagHandlerCtxt = nullptr);
1394 Input(MemoryBufferRef Input,
1395 void *Ctxt = nullptr,
1396 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1397 void *DiagHandlerCtxt = nullptr);
1398 ~Input() override;
1399
1400 // Check if there was an syntax or semantic error during parsing.
1401 std::error_code error();
1402
1403private:
1404 bool outputting() const override;
1405 bool mapTag(StringRef, bool) override;
1406 void beginMapping() override;
1407 void endMapping() override;
1408 bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1409 void postflightKey(void *) override;
1410 std::vector<StringRef> keys() override;
1411 void beginFlowMapping() override;
1412 void endFlowMapping() override;
1413 unsigned beginSequence() override;
1414 void endSequence() override;
1415 bool preflightElement(unsigned index, void *&) override;
1416 void postflightElement(void *) override;
1417 unsigned beginFlowSequence() override;
1418 bool preflightFlowElement(unsigned , void *&) override;
1419 void postflightFlowElement(void *) override;
1420 void endFlowSequence() override;
1421 void beginEnumScalar() override;
1422 bool matchEnumScalar(const char*, bool) override;
1423 bool matchEnumFallback() override;
1424 void endEnumScalar() override;
1425 bool beginBitSetScalar(bool &) override;
1426 bool bitSetMatch(const char *, bool ) override;
1427 void endBitSetScalar() override;
1428 void scalarString(StringRef &, QuotingType) override;
1429 void blockScalarString(StringRef &) override;
1430 void scalarTag(std::string &) override;
1431 NodeKind getNodeKind() override;
1432 void setError(const Twine &message) override;
1433 bool canElideEmptySequence() override;
1434
1435 class HNode {
1436 virtual void anchor();
1437
1438 public:
1439 HNode(Node *n) : _node(n) { }
1440 virtual ~HNode() = default;
1441
1442 static bool classof(const HNode *) { return true; }
1443
1444 Node *_node;
1445 };
1446
1447 class EmptyHNode : public HNode {
1448 void anchor() override;
1449
1450 public:
1451 EmptyHNode(Node *n) : HNode(n) { }
1452
1453 static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1454
1455 static bool classof(const EmptyHNode *) { return true; }
1456 };
1457
1458 class ScalarHNode : public HNode {
1459 void anchor() override;
1460
1461 public:
1462 ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1463
1464 StringRef value() const { return _value; }
1465
1466 static bool classof(const HNode *n) {
1467 return ScalarNode::classof(n->_node) ||
1468 BlockScalarNode::classof(n->_node);
1469 }
1470
1471 static bool classof(const ScalarHNode *) { return true; }
1472
1473 protected:
1474 StringRef _value;
1475 };
1476
1477 class MapHNode : public HNode {
1478 void anchor() override;
1479
1480 public:
1481 MapHNode(Node *n) : HNode(n) { }
1482
1483 static bool classof(const HNode *n) {
1484 return MappingNode::classof(n->_node);
1485 }
1486
1487 static bool classof(const MapHNode *) { return true; }
1488
1489 using NameToNode = StringMap<std::unique_ptr<HNode>>;
1490
1491 NameToNode Mapping;
1492 SmallVector<std::string, 6> ValidKeys;
1493 };
1494
1495 class SequenceHNode : public HNode {
1496 void anchor() override;
1497
1498 public:
1499 SequenceHNode(Node *n) : HNode(n) { }
1500
1501 static bool classof(const HNode *n) {
1502 return SequenceNode::classof(n->_node);
1503 }
1504
1505 static bool classof(const SequenceHNode *) { return true; }
1506
1507 std::vector<std::unique_ptr<HNode>> Entries;
1508 };
1509
1510 std::unique_ptr<Input::HNode> createHNodes(Node *node);
1511 void setError(HNode *hnode, const Twine &message);
1512 void setError(Node *node, const Twine &message);
1513
1514public:
1515 // These are only used by operator>>. They could be private
1516 // if those templated things could be made friends.
1517 bool setCurrentDocument();
1518 bool nextDocument();
1519
1520 /// Returns the current node that's being parsed by the YAML Parser.
1521 const Node *getCurrentNode() const;
1522
1523private:
1524 SourceMgr SrcMgr; // must be before Strm
1525 std::unique_ptr<llvm::yaml::Stream> Strm;
1526 std::unique_ptr<HNode> TopNode;
1527 std::error_code EC;
1528 BumpPtrAllocator StringAllocator;
1529 document_iterator DocIterator;
1530 std::vector<bool> BitValuesUsed;
1531 HNode *CurrentNode = nullptr;
1532 bool ScalarMatchFound = false;
1533};
1534
1535///
1536/// The Output class is used to generate a yaml document from in-memory structs
1537/// and vectors.
1538///
1539class Output : public IO {
1540public:
1541 Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1542 ~Output() override;
1543
1544 /// Set whether or not to output optional values which are equal
1545 /// to the default value. By default, when outputting if you attempt
1546 /// to write a value that is equal to the default, the value gets ignored.
1547 /// Sometimes, it is useful to be able to see these in the resulting YAML
1548 /// anyway.
1549 void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1550
1551 bool outputting() const override;
1552 bool mapTag(StringRef, bool) override;
1553 void beginMapping() override;
1554 void endMapping() override;
1555 bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1556 void postflightKey(void *) override;
1557 std::vector<StringRef> keys() override;
1558 void beginFlowMapping() override;
1559 void endFlowMapping() override;
1560 unsigned beginSequence() override;
1561 void endSequence() override;
1562 bool preflightElement(unsigned, void *&) override;
1563 void postflightElement(void *) override;
1564 unsigned beginFlowSequence() override;
1565 bool preflightFlowElement(unsigned, void *&) override;
1566 void postflightFlowElement(void *) override;
1567 void endFlowSequence() override;
1568 void beginEnumScalar() override;
1569 bool matchEnumScalar(const char*, bool) override;
1570 bool matchEnumFallback() override;
1571 void endEnumScalar() override;
1572 bool beginBitSetScalar(bool &) override;
1573 bool bitSetMatch(const char *, bool ) override;
1574 void endBitSetScalar() override;
1575 void scalarString(StringRef &, QuotingType) override;
1576 void blockScalarString(StringRef &) override;
1577 void scalarTag(std::string &) override;
1578 NodeKind getNodeKind() override;
1579 void setError(const Twine &message) override;
1580 bool canElideEmptySequence() override;
1581
1582 // These are only used by operator<<. They could be private
1583 // if that templated operator could be made a friend.
1584 void beginDocuments();
1585 bool preflightDocument(unsigned);
1586 void postflightDocument();
1587 void endDocuments();
1588
1589private:
1590 void output(StringRef s);
1591 void outputUpToEndOfLine(StringRef s);
1592 void newLineCheck();
1593 void outputNewLine();
1594 void paddedKey(StringRef key);
1595 void flowKey(StringRef Key);
1596
1597 enum InState {
1598 inSeqFirstElement,
1599 inSeqOtherElement,
1600 inFlowSeqFirstElement,
1601 inFlowSeqOtherElement,
1602 inMapFirstKey,
1603 inMapOtherKey,
1604 inFlowMapFirstKey,
1605 inFlowMapOtherKey
1606 };
1607
1608 static bool inSeqAnyElement(InState State);
1609 static bool inFlowSeqAnyElement(InState State);
1610 static bool inMapAnyKey(InState State);
1611 static bool inFlowMapAnyKey(InState State);
1612
1613 raw_ostream &Out;
1614 int WrapColumn;
1615 SmallVector<InState, 8> StateStack;
1616 int Column = 0;
1617 int ColumnAtFlowStart = 0;
1618 int ColumnAtMapFlowStart = 0;
1619 bool NeedBitValueComma = false;
1620 bool NeedFlowSequenceComma = false;
1621 bool EnumerationMatchFound = false;
1622 bool WriteDefaultValues = false;
1623 StringRef Padding;
1624 StringRef PaddingBeforeContainer;
1625};
1626
1627/// YAML I/O does conversion based on types. But often native data types
1628/// are just a typedef of built in intergral types (e.g. int). But the C++
1629/// type matching system sees through the typedef and all the typedefed types
1630/// look like a built in type. This will cause the generic YAML I/O conversion
1631/// to be used. To provide better control over the YAML conversion, you can
1632/// use this macro instead of typedef. It will create a class with one field
1633/// and automatic conversion operators to and from the base type.
1634/// Based on BOOST_STRONG_TYPEDEF
1635#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; };
\
1636 struct _type { \
1637 _type() = default; \
1638 _type(const _base v) : value(v) {} \
1639 _type(const _type &v) = default; \
1640 _type &operator=(const _type &rhs) = default; \
1641 _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1642 operator const _base & () const { return value; } \
1643 bool operator==(const _type &rhs) const { return value == rhs.value; } \
1644 bool operator==(const _base &rhs) const { return value == rhs; } \
1645 bool operator<(const _type &rhs) const { return value < rhs.value; } \
1646 _base value; \
1647 using BaseType = _base; \
1648 };
1649
1650///
1651/// Use these types instead of uintXX_t in any mapping to have
1652/// its yaml output formatted as hexadecimal.
1653///
1654LLVM_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; };
1655LLVM_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; };
1656LLVM_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; };
1657LLVM_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; };
1658
1659template<>
1660struct ScalarTraits<Hex8> {
1661 static void output(const Hex8 &, void *, raw_ostream &);
1662 static StringRef input(StringRef, void *, Hex8 &);
1663 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1664};
1665
1666template<>
1667struct ScalarTraits<Hex16> {
1668 static void output(const Hex16 &, void *, raw_ostream &);
1669 static StringRef input(StringRef, void *, Hex16 &);
1670 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1671};
1672
1673template<>
1674struct ScalarTraits<Hex32> {
1675 static void output(const Hex32 &, void *, raw_ostream &);
1676 static StringRef input(StringRef, void *, Hex32 &);
1677 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1678};
1679
1680template<>
1681struct ScalarTraits<Hex64> {
1682 static void output(const Hex64 &, void *, raw_ostream &);
1683 static StringRef input(StringRef, void *, Hex64 &);
1684 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1685};
1686
1687// Define non-member operator>> so that Input can stream in a document list.
1688template <typename T>
1689inline std::enable_if_t<has_DocumentListTraits<T>::value, Input &>
1690operator>>(Input &yin, T &docList) {
1691 int i = 0;
1692 EmptyContext Ctx;
1693 while ( yin.setCurrentDocument() ) {
1694 yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1695 if ( yin.error() )
1696 return yin;
1697 yin.nextDocument();
1698 ++i;
1699 }
1700 return yin;
1701}
1702
1703// Define non-member operator>> so that Input can stream in a map as a document.
1704template <typename T>
1705inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Input &>
1706operator>>(Input &yin, T &docMap) {
1707 EmptyContext Ctx;
1708 yin.setCurrentDocument();
1709 yamlize(yin, docMap, true, Ctx);
1710 return yin;
1711}
1712
1713// Define non-member operator>> so that Input can stream in a sequence as
1714// a document.
1715template <typename T>
1716inline std::enable_if_t<has_SequenceTraits<T>::value, Input &>
1717operator>>(Input &yin, T &docSeq) {
1718 EmptyContext Ctx;
1719 if (yin.setCurrentDocument())
1720 yamlize(yin, docSeq, true, Ctx);
1721 return yin;
1722}
1723
1724// Define non-member operator>> so that Input can stream in a block scalar.
1725template <typename T>
1726inline std::enable_if_t<has_BlockScalarTraits<T>::value, Input &>
1727operator>>(Input &In, T &Val) {
1728 EmptyContext Ctx;
1729 if (In.setCurrentDocument())
1730 yamlize(In, Val, true, Ctx);
1731 return In;
1732}
1733
1734// Define non-member operator>> so that Input can stream in a string map.
1735template <typename T>
1736inline std::enable_if_t<has_CustomMappingTraits<T>::value, Input &>
1737operator>>(Input &In, T &Val) {
1738 EmptyContext Ctx;
1739 if (In.setCurrentDocument())
1740 yamlize(In, Val, true, Ctx);
1741 return In;
1742}
1743
1744// Define non-member operator>> so that Input can stream in a polymorphic type.
1745template <typename T>
1746inline std::enable_if_t<has_PolymorphicTraits<T>::value, Input &>
1747operator>>(Input &In, T &Val) {
1748 EmptyContext Ctx;
1749 if (In.setCurrentDocument())
1750 yamlize(In, Val, true, Ctx);
1751 return In;
1752}
1753
1754// Provide better error message about types missing a trait specialization
1755template <typename T>
1756inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Input &>
1757operator>>(Input &yin, T &docSeq) {
1758 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1759 return yin;
1760}
1761
1762// Define non-member operator<< so that Output can stream out document list.
1763template <typename T>
1764inline std::enable_if_t<has_DocumentListTraits<T>::value, Output &>
1765operator<<(Output &yout, T &docList) {
1766 EmptyContext Ctx;
1767 yout.beginDocuments();
1768 const size_t count = DocumentListTraits<T>::size(yout, docList);
1769 for(size_t i=0; i < count; ++i) {
1770 if ( yout.preflightDocument(i) ) {
1771 yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1772 Ctx);
1773 yout.postflightDocument();
1774 }
1775 }
1776 yout.endDocuments();
1777 return yout;
1778}
1779
1780// Define non-member operator<< so that Output can stream out a map.
1781template <typename T>
1782inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Output &>
1783operator<<(Output &yout, T &map) {
1784 EmptyContext Ctx;
1785 yout.beginDocuments();
1786 if ( yout.preflightDocument(0) ) {
1787 yamlize(yout, map, true, Ctx);
1788 yout.postflightDocument();
1789 }
1790 yout.endDocuments();
1791 return yout;
1792}
1793
1794// Define non-member operator<< so that Output can stream out a sequence.
1795template <typename T>
1796inline std::enable_if_t<has_SequenceTraits<T>::value, Output &>
1797operator<<(Output &yout, T &seq) {
1798 EmptyContext Ctx;
1799 yout.beginDocuments();
1800 if ( yout.preflightDocument(0) ) {
1801 yamlize(yout, seq, true, Ctx);
1802 yout.postflightDocument();
1803 }
1804 yout.endDocuments();
1805 return yout;
1806}
1807
1808// Define non-member operator<< so that Output can stream out a block scalar.
1809template <typename T>
1810inline std::enable_if_t<has_BlockScalarTraits<T>::value, Output &>
1811operator<<(Output &Out, T &Val) {
1812 EmptyContext Ctx;
1813 Out.beginDocuments();
1814 if (Out.preflightDocument(0)) {
1815 yamlize(Out, Val, true, Ctx);
1816 Out.postflightDocument();
1817 }
1818 Out.endDocuments();
1819 return Out;
1820}
1821
1822// Define non-member operator<< so that Output can stream out a string map.
1823template <typename T>
1824inline std::enable_if_t<has_CustomMappingTraits<T>::value, Output &>
1825operator<<(Output &Out, T &Val) {
1826 EmptyContext Ctx;
1827 Out.beginDocuments();
1828 if (Out.preflightDocument(0)) {
1829 yamlize(Out, Val, true, Ctx);
1830 Out.postflightDocument();
1831 }
1832 Out.endDocuments();
1833 return Out;
1834}
1835
1836// Define non-member operator<< so that Output can stream out a polymorphic
1837// type.
1838template <typename T>
1839inline std::enable_if_t<has_PolymorphicTraits<T>::value, Output &>
1840operator<<(Output &Out, T &Val) {
1841 EmptyContext Ctx;
1842 Out.beginDocuments();
1843 if (Out.preflightDocument(0)) {
1844 // FIXME: The parser does not support explicit documents terminated with a
1845 // plain scalar; the end-marker is included as part of the scalar token.
1846 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-11~++20200309111110+2c36c23f347/llvm/include/llvm/Support/YAMLTraits.h"
, 1846, __PRETTY_FUNCTION__))
;
1847 yamlize(Out, Val, true, Ctx);
1848 Out.postflightDocument();
1849 }
1850 Out.endDocuments();
1851 return Out;
1852}
1853
1854// Provide better error message about types missing a trait specialization
1855template <typename T>
1856inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Output &>
1857operator<<(Output &yout, T &seq) {
1858 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1859 return yout;
1860}
1861
1862template <bool B> struct IsFlowSequenceBase {};
1863template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1864
1865template <typename T, bool Flow>
1866struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1867private:
1868 using type = typename T::value_type;
1869
1870public:
1871 static size_t size(IO &io, T &seq) { return seq.size(); }
1872
1873 static type &element(IO &io, T &seq, size_t index) {
1874 if (index >= seq.size())
1875 seq.resize(index + 1);
1876 return seq[index];
1877 }
1878};
1879
1880// Simple helper to check an expression can be used as a bool-valued template
1881// argument.
1882template <bool> struct CheckIsBool { static const bool value = true; };
1883
1884// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1885// SequenceTraits that do the obvious thing.
1886template <typename T>
1887struct SequenceTraits<
1888 std::vector<T>,
1889 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1890 : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1891template <typename T, unsigned N>
1892struct SequenceTraits<
1893 SmallVector<T, N>,
1894 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1895 : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1896template <typename T>
1897struct SequenceTraits<
1898 SmallVectorImpl<T>,
1899 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1900 : SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
1901
1902// Sequences of fundamental types use flow formatting.
1903template <typename T>
1904struct SequenceElementTraits<T,
1905 std::enable_if_t<std::is_fundamental<T>::value>> {
1906 static const bool flow = true;
1907};
1908
1909// Sequences of strings use block formatting.
1910template<> struct SequenceElementTraits<std::string> {
1911 static const bool flow = false;
1912};
1913template<> struct SequenceElementTraits<StringRef> {
1914 static const bool flow = false;
1915};
1916template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1917 static const bool flow = false;
1918};
1919
1920/// Implementation of CustomMappingTraits for std::map<std::string, T>.
1921template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1922 using map_type = std::map<std::string, T>;
1923
1924 static void inputOne(IO &io, StringRef key, map_type &v) {
1925 io.mapRequired(key.str().c_str(), v[std::string(key)]);
1926 }
1927
1928 static void output(IO &io, map_type &v) {
1929 for (auto &p : v)
1930 io.mapRequired(p.first.c_str(), p.second);
1931 }
1932};
1933
1934} // end namespace yaml
1935} // end namespace llvm
1936
1937#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; }; } }
\
1938 namespace llvm { \
1939 namespace yaml { \
1940 static_assert( \
1941 !std::is_fundamental<TYPE>::value && \
1942 !std::is_same<TYPE, std::string>::value && \
1943 !std::is_same<TYPE, llvm::StringRef>::value, \
1944 "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
1945 template <> struct SequenceElementTraits<TYPE> { \
1946 static const bool flow = FLOW; \
1947 }; \
1948 } \
1949 }
1950
1951/// Utility for declaring that a std::vector of a particular type
1952/// should be considered a YAML sequence.
1953#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; }; } }
\
1954 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; }; } }
1955
1956/// Utility for declaring that a std::vector of a particular type
1957/// should be considered a YAML flow sequence.
1958#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; }; } }
\
1959 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; }; } }
1960
1961#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)namespace llvm { namespace yaml { template <> struct MappingTraits
<Type> { static void mapping(IO &IO, Type &Obj)
; }; } }
\
1962 namespace llvm { \
1963 namespace yaml { \
1964 template <> struct MappingTraits<Type> { \
1965 static void mapping(IO &IO, Type &Obj); \
1966 }; \
1967 } \
1968 }
1969
1970#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<Type> { static void enumeration(IO &io, Type &
Value); }; } }
\
1971 namespace llvm { \
1972 namespace yaml { \
1973 template <> struct ScalarEnumerationTraits<Type> { \
1974 static void enumeration(IO &io, Type &Value); \
1975 }; \
1976 } \
1977 }
1978
1979#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<Type> { static void bitset(IO &IO, Type &Options
); }; } }
\
1980 namespace llvm { \
1981 namespace yaml { \
1982 template <> struct ScalarBitSetTraits<Type> { \
1983 static void bitset(IO &IO, Type &Options); \
1984 }; \
1985 } \
1986 }
1987
1988#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; } }; } }
\
1989 namespace llvm { \
1990 namespace yaml { \
1991 template <> struct ScalarTraits<Type> { \
1992 static void output(const Type &Value, void *ctx, raw_ostream &Out); \
1993 static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
1994 static QuotingType mustQuote(StringRef) { return MustQuote; } \
1995 }; \
1996 } \
1997 }
1998
1999/// Utility for declaring that a std::vector of a particular type
2000/// should be considered a YAML document list.
2001#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> {}; } }
\
2002 namespace llvm { \
2003 namespace yaml { \
2004 template <unsigned N> \
2005 struct DocumentListTraits<SmallVector<_type, N>> \
2006 : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
2007 template <> \
2008 struct DocumentListTraits<std::vector<_type>> \
2009 : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
2010 } \
2011 }
2012
2013/// Utility for declaring that std::map<std::string, _type> should be considered
2014/// a YAML map.
2015#define LLVM_YAML_IS_STRING_MAP(_type)namespace llvm { namespace yaml { template <> struct CustomMappingTraits
<std::map<std::string, _type>> : public StdMapStringCustomMappingTraitsImpl
<_type> {}; } }
\
2016 namespace llvm { \
2017 namespace yaml { \
2018 template <> \
2019 struct CustomMappingTraits<std::map<std::string, _type>> \
2020 : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
2021 } \
2022 }
2023
2024LLVM_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; }; } }
2025LLVM_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; }; } }
2026LLVM_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; }; } }
2027LLVM_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; }; } }
2028
2029#endif // LLVM_SUPPORT_YAMLTRAITS_H