Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -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 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/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-12/lib/clang/12.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-12~++20201129111111+e987fbdd85d/build-llvm/lib/ObjectYAML -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-11-29-190409-37574-1 -x c++ /build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/llvm/lib/ObjectYAML/ELFYAML.cpp

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

/build/llvm-toolchain-snapshot-12~++20201129111111+e987fbdd85d/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/DWARFYAML.h"
20#include "llvm/ObjectYAML/YAML.h"
21#include "llvm/Support/YAMLTraits.h"
22#include <cstdint>
23#include <memory>
24#include <vector>
25
26namespace llvm {
27namespace ELFYAML {
28
29StringRef dropUniqueSuffix(StringRef S);
30std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
31
32// These types are invariant across 32/64-bit ELF, so for simplicity just
33// directly give them their exact sizes. We don't need to worry about
34// endianness because these are just the types in the YAMLIO structures,
35// and are appropriately converted to the necessary endianness when
36// reading/generating binary object files.
37// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
38// the common prefix of the respective constants. E.g. ELF_EM corresponds
39// to the `e_machine` constants, like `EM_X86_64`.
40// In the future, these would probably be better suited by C++11 enum
41// class's with appropriate fixed underlying type.
42LLVM_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
; };
43LLVM_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
; };
44LLVM_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
; };
45LLVM_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; }
;
46LLVM_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; }
;
47LLVM_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; }
;
48// Just use 64, since it can hold 32-bit values too.
49LLVM_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
; };
50// Just use 64, since it can hold 32-bit values too.
51LLVM_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; };
52LLVM_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
; };
53LLVM_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'
18
The left operand of '==' is a garbage value
54LLVM_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; };
55LLVM_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; };
56// Just use 64, since it can hold 32-bit values too.
57LLVM_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; };
58LLVM_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; };
59LLVM_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; };
60LLVM_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; };
61
62LLVM_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; }
;
63LLVM_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; }
;
64LLVM_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;
};
65LLVM_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;
};
66LLVM_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;
};
67LLVM_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; };
68
69LLVM_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
; };
70LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)struct YAMLIntUInt { YAMLIntUInt() = default; YAMLIntUInt(const
int64_t v) : value(v) {} YAMLIntUInt(const YAMLIntUInt &
v) = default; YAMLIntUInt &operator=(const YAMLIntUInt &
rhs) = default; YAMLIntUInt &operator=(const int64_t &
rhs) { value = rhs; return *this; } operator const int64_t &
() const { return value; } bool operator==(const YAMLIntUInt
&rhs) const { return value == rhs.value; } bool operator
==(const int64_t &rhs) const { return value == rhs; } bool
operator<(const YAMLIntUInt &rhs) const { return value
< rhs.value; } int64_t value; using BaseType = int64_t; }
;
71
72// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
73// since 64-bit can hold 32-bit values too.
74struct FileHeader {
75 ELF_ELFCLASS Class;
76 ELF_ELFDATA Data;
77 ELF_ELFOSABI OSABI;
78 llvm::yaml::Hex8 ABIVersion;
79 ELF_ET Type;
80 Optional<ELF_EM> Machine;
81 ELF_EF Flags;
82 llvm::yaml::Hex64 Entry;
83
84 Optional<llvm::yaml::Hex64> EPhOff;
85 Optional<llvm::yaml::Hex16> EPhEntSize;
86 Optional<llvm::yaml::Hex16> EPhNum;
87 Optional<llvm::yaml::Hex16> EShEntSize;
88 Optional<llvm::yaml::Hex64> EShOff;
89 Optional<llvm::yaml::Hex16> EShNum;
90 Optional<llvm::yaml::Hex16> EShStrNdx;
91};
92
93struct SectionHeader {
94 StringRef Name;
95};
96
97struct SectionHeaderTable {
98 Optional<std::vector<SectionHeader>> Sections;
99 Optional<std::vector<SectionHeader>> Excluded;
100 Optional<bool> NoHeaders;
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 BBAddrMapEntry {
126 struct BBEntry {
127 llvm::yaml::Hex32 AddressOffset;
128 llvm::yaml::Hex32 Size;
129 llvm::yaml::Hex32 Metadata;
130 };
131 llvm::yaml::Hex64 Address;
132 Optional<std::vector<BBEntry>> BBEntries;
133};
134
135struct StackSizeEntry {
136 llvm::yaml::Hex64 Address;
137 llvm::yaml::Hex64 Size;
138};
139
140struct NoteEntry {
141 StringRef Name;
142 yaml::BinaryRef Desc;
143 llvm::yaml::Hex32 Type;
144};
145
146struct Chunk {
147 enum class ChunkKind {
148 Dynamic,
149 Group,
150 RawContent,
151 Relocation,
152 Relr,
153 NoBits,
154 Note,
155 Hash,
156 GnuHash,
157 Verdef,
158 Verneed,
159 StackSizes,
160 SymtabShndxSection,
161 Symver,
162 ARMIndexTable,
163 MipsABIFlags,
164 Addrsig,
165 Fill,
166 LinkerOptions,
167 DependentLibraries,
168 CallGraphProfile,
169 BBAddrMap
170 };
171
172 ChunkKind Kind;
173 StringRef Name;
174 Optional<llvm::yaml::Hex64> Offset;
175
176 Chunk(ChunkKind K) : Kind(K) {}
177 virtual ~Chunk();
178};
179
180struct Section : public Chunk {
181 ELF_SHT Type;
182 Optional<ELF_SHF> Flags;
183 Optional<llvm::yaml::Hex64> Address;
184 Optional<StringRef> Link;
185 llvm::yaml::Hex64 AddressAlign;
186 Optional<llvm::yaml::Hex64> EntSize;
187
188 Optional<yaml::BinaryRef> Content;
189 Optional<llvm::yaml::Hex64> Size;
190
191 // Usually sections are not created implicitly, but loaded from YAML.
192 // When they are, this flag is used to signal about that.
193 bool IsImplicit;
194
195 // Holds the original section index.
196 unsigned OriginalSecNdx;
197
198 Section(ChunkKind Kind, bool IsImplicit = false)
199 : Chunk(Kind), IsImplicit(IsImplicit) {}
200
201 static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; }
202
203 // Some derived sections might have their own special entries. This method
204 // returns a vector of <entry name, is used> pairs. It is used for section
205 // validation.
206 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
207 return {};
208 };
209
210 // The following members are used to override section fields which is
211 // useful for creating invalid objects.
212
213 // This can be used to override the sh_addralign field.
214 Optional<llvm::yaml::Hex64> ShAddrAlign;
215
216 // This can be used to override the offset stored in the sh_name field.
217 // It does not affect the name stored in the string table.
218 Optional<llvm::yaml::Hex64> ShName;
219
220 // This can be used to override the sh_offset field. It does not place the
221 // section data at the offset specified.
222 Optional<llvm::yaml::Hex64> ShOffset;
223
224 // This can be used to override the sh_size field. It does not affect the
225 // content written.
226 Optional<llvm::yaml::Hex64> ShSize;
227
228 // This can be used to override the sh_flags field.
229 Optional<llvm::yaml::Hex64> ShFlags;
230
231 // This can be used to override the sh_type field. It is useful when we
232 // want to use specific YAML keys for a section of a particular type to
233 // describe the content, but still want to have a different final type
234 // for the section.
235 Optional<ELF_SHT> ShType;
236};
237
238// Fill is a block of data which is placed outside of sections. It is
239// not present in the sections header table, but it might affect the output file
240// size and program headers produced.
241struct Fill : Chunk {
242 Optional<yaml::BinaryRef> Pattern;
243 llvm::yaml::Hex64 Size;
244
245 Fill() : Chunk(ChunkKind::Fill) {}
246
247 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
248};
249
250struct BBAddrMapSection : Section {
251 Optional<std::vector<BBAddrMapEntry>> Entries;
252
253 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
254
255 std::vector<std::pair<StringRef, bool>> getEntries() const override {
256 return {{"Entries", Entries.hasValue()}};
257 };
258
259 static bool classof(const Chunk *S) {
260 return S->Kind == ChunkKind::BBAddrMap;
261 }
262};
263
264struct StackSizesSection : Section {
265 Optional<std::vector<StackSizeEntry>> Entries;
266
267 StackSizesSection() : Section(ChunkKind::StackSizes) {}
268
269 std::vector<std::pair<StringRef, bool>> getEntries() const override {
270 return {{"Entries", Entries.hasValue()}};
271 };
272
273 static bool classof(const Chunk *S) {
274 return S->Kind == ChunkKind::StackSizes;
275 }
276
277 static bool nameMatches(StringRef Name) {
278 return Name == ".stack_sizes";
279 }
280};
281
282struct DynamicSection : Section {
283 Optional<std::vector<DynamicEntry>> Entries;
284
285 DynamicSection() : Section(ChunkKind::Dynamic) {}
286
287 std::vector<std::pair<StringRef, bool>> getEntries() const override {
288 return {{"Entries", Entries.hasValue()}};
289 };
290
291 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
292};
293
294struct RawContentSection : Section {
295 Optional<llvm::yaml::Hex64> Info;
296
297 RawContentSection() : Section(ChunkKind::RawContent) {}
298
299 static bool classof(const Chunk *S) {
300 return S->Kind == ChunkKind::RawContent;
301 }
302
303 // Is used when a content is read as an array of bytes.
304 Optional<std::vector<uint8_t>> ContentBuf;
305};
306
307struct NoBitsSection : Section {
308 NoBitsSection() : Section(ChunkKind::NoBits) {}
309
310 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
311};
312
313struct NoteSection : Section {
314 Optional<std::vector<ELFYAML::NoteEntry>> Notes;
315
316 NoteSection() : Section(ChunkKind::Note) {}
317
318 std::vector<std::pair<StringRef, bool>> getEntries() const override {
319 return {{"Notes", Notes.hasValue()}};
320 };
321
322 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
323};
324
325struct HashSection : Section {
326 Optional<std::vector<uint32_t>> Bucket;
327 Optional<std::vector<uint32_t>> Chain;
328
329 std::vector<std::pair<StringRef, bool>> getEntries() const override {
330 return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
331 };
332
333 // The following members are used to override section fields.
334 // This is useful for creating invalid objects.
335 Optional<llvm::yaml::Hex64> NBucket;
336 Optional<llvm::yaml::Hex64> NChain;
337
338 HashSection() : Section(ChunkKind::Hash) {}
339
340 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
341};
342
343struct GnuHashHeader {
344 // The number of hash buckets.
345 // Not used when dumping the object, but can be used to override
346 // the real number of buckets when emiting an object from a YAML document.
347 Optional<llvm::yaml::Hex32> NBuckets;
348
349 // Index of the first symbol in the dynamic symbol table
350 // included in the hash table.
351 llvm::yaml::Hex32 SymNdx;
352
353 // The number of words in the Bloom filter.
354 // Not used when dumping the object, but can be used to override the real
355 // number of words in the Bloom filter when emiting an object from a YAML
356 // document.
357 Optional<llvm::yaml::Hex32> MaskWords;
358
359 // A shift constant used by the Bloom filter.
360 llvm::yaml::Hex32 Shift2;
361};
362
363struct GnuHashSection : Section {
364 Optional<GnuHashHeader> Header;
365 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
366 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
367 Optional<std::vector<llvm::yaml::Hex32>> HashValues;
368
369 GnuHashSection() : Section(ChunkKind::GnuHash) {}
370
371 std::vector<std::pair<StringRef, bool>> getEntries() const override {
372 return {{"Header", Header.hasValue()},
373 {"BloomFilter", BloomFilter.hasValue()},
374 {"HashBuckets", HashBuckets.hasValue()},
375 {"HashValues", HashValues.hasValue()}};
376 };
377
378 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
379};
380
381struct VernauxEntry {
382 uint32_t Hash;
383 uint16_t Flags;
384 uint16_t Other;
385 StringRef Name;
386};
387
388struct VerneedEntry {
389 uint16_t Version;
390 StringRef File;
391 std::vector<VernauxEntry> AuxV;
392};
393
394struct VerneedSection : Section {
395 Optional<std::vector<VerneedEntry>> VerneedV;
396 llvm::yaml::Hex64 Info;
397
398 VerneedSection() : Section(ChunkKind::Verneed) {}
399
400 std::vector<std::pair<StringRef, bool>> getEntries() const override {
401 return {{"Dependencies", VerneedV.hasValue()}};
402 };
403
404 static bool classof(const Chunk *S) {
405 return S->Kind == ChunkKind::Verneed;
406 }
407};
408
409struct AddrsigSection : Section {
410 Optional<std::vector<YAMLFlowString>> Symbols;
411
412 AddrsigSection() : Section(ChunkKind::Addrsig) {}
413
414 std::vector<std::pair<StringRef, bool>> getEntries() const override {
415 return {{"Symbols", Symbols.hasValue()}};
416 };
417
418 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
419};
420
421struct LinkerOption {
422 StringRef Key;
423 StringRef Value;
424};
425
426struct LinkerOptionsSection : Section {
427 Optional<std::vector<LinkerOption>> Options;
428
429 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
430
431 std::vector<std::pair<StringRef, bool>> getEntries() const override {
432 return {{"Options", Options.hasValue()}};
433 };
434
435 static bool classof(const Chunk *S) {
436 return S->Kind == ChunkKind::LinkerOptions;
437 }
438};
439
440struct DependentLibrariesSection : Section {
441 Optional<std::vector<YAMLFlowString>> Libs;
442
443 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
444
445 std::vector<std::pair<StringRef, bool>> getEntries() const override {
446 return {{"Libraries", Libs.hasValue()}};
447 };
448
449 static bool classof(const Chunk *S) {
450 return S->Kind == ChunkKind::DependentLibraries;
451 }
452};
453
454// Represents the call graph profile section entry.
455struct CallGraphEntry {
456 // The symbol of the source of the edge.
457 StringRef From;
458 // The symbol index of the destination of the edge.
459 StringRef To;
460 // The weight of the edge.
461 uint64_t Weight;
462};
463
464struct CallGraphProfileSection : Section {
465 Optional<std::vector<CallGraphEntry>> Entries;
466
467 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
468
469 std::vector<std::pair<StringRef, bool>> getEntries() const override {
470 return {{"Entries", Entries.hasValue()}};
471 };
472
473 static bool classof(const Chunk *S) {
474 return S->Kind == ChunkKind::CallGraphProfile;
475 }
476};
477
478struct SymverSection : Section {
479 Optional<std::vector<uint16_t>> Entries;
480
481 SymverSection() : Section(ChunkKind::Symver) {}
482
483 std::vector<std::pair<StringRef, bool>> getEntries() const override {
484 return {{"Entries", Entries.hasValue()}};
485 };
486
487 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
488};
489
490struct VerdefEntry {
491 uint16_t Version;
492 uint16_t Flags;
493 uint16_t VersionNdx;
494 uint32_t Hash;
495 std::vector<StringRef> VerNames;
496};
497
498struct VerdefSection : Section {
499 Optional<std::vector<VerdefEntry>> Entries;
500
501 llvm::yaml::Hex64 Info;
502
503 VerdefSection() : Section(ChunkKind::Verdef) {}
504
505 std::vector<std::pair<StringRef, bool>> getEntries() const override {
506 return {{"Entries", Entries.hasValue()}};
507 };
508
509 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
510};
511
512struct GroupSection : Section {
513 // Members of a group contain a flag and a list of section indices
514 // that are part of the group.
515 Optional<std::vector<SectionOrType>> Members;
516 Optional<StringRef> Signature; /* Info */
517
518 GroupSection() : Section(ChunkKind::Group) {}
519
520 std::vector<std::pair<StringRef, bool>> getEntries() const override {
521 return {{"Members", Members.hasValue()}};
522 };
523
524 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
525};
526
527struct Relocation {
528 llvm::yaml::Hex64 Offset;
529 YAMLIntUInt Addend;
530 ELF_REL Type;
531 Optional<StringRef> Symbol;
532};
533
534struct RelocationSection : Section {
535 Optional<std::vector<Relocation>> Relocations;
536 StringRef RelocatableSec; /* Info */
537
538 RelocationSection() : Section(ChunkKind::Relocation) {}
539
540 std::vector<std::pair<StringRef, bool>> getEntries() const override {
541 return {{"Relocations", Relocations.hasValue()}};
542 };
543
544 static bool classof(const Chunk *S) {
545 return S->Kind == ChunkKind::Relocation;
546 }
547};
548
549struct RelrSection : Section {
550 Optional<std::vector<llvm::yaml::Hex64>> Entries;
551
552 RelrSection() : Section(ChunkKind::Relr) {}
553
554 std::vector<std::pair<StringRef, bool>> getEntries() const override {
555 return {{"Entries", Entries.hasValue()}};
556 };
557
558 static bool classof(const Chunk *S) {
559 return S->Kind == ChunkKind::Relr;
560 }
561};
562
563struct SymtabShndxSection : Section {
564 Optional<std::vector<uint32_t>> Entries;
565
566 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
567
568 std::vector<std::pair<StringRef, bool>> getEntries() const override {
569 return {{"Entries", Entries.hasValue()}};
570 };
571
572 static bool classof(const Chunk *S) {
573 return S->Kind == ChunkKind::SymtabShndxSection;
574 }
575};
576
577struct ARMIndexTableEntry {
578 llvm::yaml::Hex32 Offset;
579 llvm::yaml::Hex32 Value;
580};
581
582struct ARMIndexTableSection : Section {
583 Optional<std::vector<ARMIndexTableEntry>> Entries;
584
585 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
586
587 std::vector<std::pair<StringRef, bool>> getEntries() const override {
588 return {{"Entries", Entries.hasValue()}};
589 };
590
591 static bool classof(const Chunk *S) {
592 return S->Kind == ChunkKind::ARMIndexTable;
593 }
594};
595
596// Represents .MIPS.abiflags section
597struct MipsABIFlags : Section {
598 llvm::yaml::Hex16 Version;
599 MIPS_ISA ISALevel;
600 llvm::yaml::Hex8 ISARevision;
601 MIPS_AFL_REG GPRSize;
602 MIPS_AFL_REG CPR1Size;
603 MIPS_AFL_REG CPR2Size;
604 MIPS_ABI_FP FpABI;
605 MIPS_AFL_EXT ISAExtension;
606 MIPS_AFL_ASE ASEs;
607 MIPS_AFL_FLAGS1 Flags1;
608 llvm::yaml::Hex32 Flags2;
609
610 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
611
612 static bool classof(const Chunk *S) {
613 return S->Kind == ChunkKind::MipsABIFlags;
614 }
615};
616
617struct ProgramHeader {
618 ELF_PT Type;
619 ELF_PF Flags;
620 llvm::yaml::Hex64 VAddr;
621 llvm::yaml::Hex64 PAddr;
622 Optional<llvm::yaml::Hex64> Align;
623 Optional<llvm::yaml::Hex64> FileSize;
624 Optional<llvm::yaml::Hex64> MemSize;
625 Optional<llvm::yaml::Hex64> Offset;
626 Optional<StringRef> FirstSec;
627 Optional<StringRef> LastSec;
628
629 // This vector contains all chunks from [FirstSec, LastSec].
630 std::vector<Chunk *> Chunks;
631};
632
633struct Object {
634 FileHeader Header;
635 Optional<SectionHeaderTable> SectionHeaders;
636 std::vector<ProgramHeader> ProgramHeaders;
637
638 // An object might contain output section descriptions as well as
639 // custom data that does not belong to any section.
640 std::vector<std::unique_ptr<Chunk>> Chunks;
641
642 // Although in reality the symbols reside in a section, it is a lot
643 // cleaner and nicer if we read them from the YAML as a separate
644 // top-level key, which automatically ensures that invariants like there
645 // being a single SHT_SYMTAB section are upheld.
646 Optional<std::vector<Symbol>> Symbols;
647 Optional<std::vector<Symbol>> DynamicSymbols;
648 Optional<DWARFYAML::Data> DWARF;
649
650 std::vector<Section *> getSections() {
651 std::vector<Section *> Ret;
652 for (const std::unique_ptr<Chunk> &Sec : Chunks)
653 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
654 Ret.push_back(S);
655 return Ret;
656 }
657
658 unsigned getMachine() const;
659};
660
661bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
662 const NoBitsSection &S);
663
664} // end namespace ELFYAML
665} // end namespace llvm
666
667LLVM_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; }; } }
668LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::BBAddrMapEntry>::value && !std::
is_same<llvm::ELFYAML::BBAddrMapEntry, std::string>::value
&& !std::is_same<llvm::ELFYAML::BBAddrMapEntry, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry> { static const bool flow = false; }; } }
669LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::BBAddrMapEntry::BBEntry>::value &&
!std::is_same<llvm::ELFYAML::BBAddrMapEntry::BBEntry, std
::string>::value && !std::is_same<llvm::ELFYAML
::BBAddrMapEntry::BBEntry, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry::BBEntry> { static const bool flow = false
; }; } }
670LLVM_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; }; } }
671LLVM_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; }; } }
672LLVM_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; }; } }
673LLVM_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; }; } }
674LLVM_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; }; } }
675LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::SectionHeader>::value && !std::
is_same<llvm::ELFYAML::SectionHeader, std::string>::value
&& !std::is_same<llvm::ELFYAML::SectionHeader, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionHeader> { static const bool flow = false; }; } }
676LLVM_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
; }; } }
677LLVM_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; }; } }
678LLVM_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; }; } }
679LLVM_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; }; } }
680LLVM_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; }; } }
681LLVM_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; }; } }
682LLVM_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; }; } }
683LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::ARMIndexTableEntry>::value && !
std::is_same<llvm::ELFYAML::ARMIndexTableEntry, std::string
>::value && !std::is_same<llvm::ELFYAML::ARMIndexTableEntry
, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ARMIndexTableEntry> { static const bool flow = false; };
} }
684
685namespace llvm {
686namespace yaml {
687
688template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
689 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
690 raw_ostream &Out);
691 static StringRef input(StringRef Scalar, void *Ctx,
692 ELFYAML::YAMLIntUInt &Val);
693 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
694};
695
696template <>
697struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
698 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
699};
700
701template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
702 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
703};
704
705template <>
706struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
707 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
708};
709
710template <>
711struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
712 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
713};
714
715template <>
716struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
717 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
718};
719
720template <>
721struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
722 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
723};
724
725template <>
726struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
727 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
728};
729
730template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
731 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
732};
733
734template <>
735struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
736 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
737};
738
739template <>
740struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
741 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
742};
743
744template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
745 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
746};
747
748template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
749 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
750};
751
752template <>
753struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
754 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
755};
756
757template <>
758struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
759 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
760};
761
762template <>
763struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
764 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
765};
766
767template <>
768struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
769 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
770};
771
772template <>
773struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
774 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
775};
776
777template <>
778struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
779 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
780};
781
782template <>
783struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
784 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
785};
786
787template <>
788struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
789 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
790};
791
792template <>
793struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
794 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
795};
796
797template <>
798struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
799 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
800};
801
802template <>
803struct MappingTraits<ELFYAML::FileHeader> {
804 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
805};
806
807template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
808 static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
809 static std::string validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
810};
811
812template <> struct MappingTraits<ELFYAML::SectionHeader> {
813 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
814};
815
816template <> struct MappingTraits<ELFYAML::ProgramHeader> {
817 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
818 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
819};
820
821template <>
822struct MappingTraits<ELFYAML::Symbol> {
823 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
824 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
825};
826
827template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
828 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
829};
830
831template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
832 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
833};
834
835template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
836 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
837};
838
839template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
840 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
841};
842
843template <> struct MappingTraits<ELFYAML::DynamicEntry> {
844 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
845};
846
847template <> struct MappingTraits<ELFYAML::NoteEntry> {
848 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
849};
850
851template <> struct MappingTraits<ELFYAML::VerdefEntry> {
852 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
853};
854
855template <> struct MappingTraits<ELFYAML::VerneedEntry> {
856 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
857};
858
859template <> struct MappingTraits<ELFYAML::VernauxEntry> {
860 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
861};
862
863template <> struct MappingTraits<ELFYAML::LinkerOption> {
864 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
865};
866
867template <> struct MappingTraits<ELFYAML::CallGraphEntry> {
868 static void mapping(IO &IO, ELFYAML::CallGraphEntry &E);
869};
870
871template <> struct MappingTraits<ELFYAML::Relocation> {
872 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
873};
874
875template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
876 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
877};
878
879template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
880 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
881 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
882};
883
884template <>
885struct MappingTraits<ELFYAML::Object> {
886 static void mapping(IO &IO, ELFYAML::Object &Object);
887};
888
889template <> struct MappingTraits<ELFYAML::SectionOrType> {
890 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
891};
892
893} // end namespace yaml
894} // end namespace llvm
895
896#endif // LLVM_OBJECTYAML_ELFYAML_H

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